CC 咖啡猫的工作空间 Coding Space

计算机组成原理

这篇解决什么问题

计算机组成原理回答的是:一台计算机内部有哪些核心部件,它们如何协作执行程序。它连接硬件和软件,是理解性能、内存、I/O、系统调用和运行时行为的基础。

学完你会掌握

  • 冯诺依曼架构的基本思想。
  • CPU、内存、总线、I/O 之间的关系。
  • 存储体系为什么要分层。
  • CPU 性能优化为什么不只是提高主频。

核心概念

经典计算机可以简化为五类部件:

部件 作用
运算器 执行算术和逻辑计算
控制器 控制指令执行流程
存储器 保存程序和数据
输入设备 接收外部输入
输出设备 输出计算结果

冯诺依曼架构的关键思想是:程序和数据都存储在内存中,CPU 按指令顺序读取并执行。

这带来一个非常重要的结果:软件可以被当作数据保存、复制和修改。现代操作系统加载程序、编译器生成可执行文件、脚本解释器读取源码,本质上都依赖「存储程序」这个思想。

冯诺依曼瓶颈

冯诺依曼架构也有天然瓶颈:CPU 处理速度远高于内存访问速度,CPU 经常需要等待数据从内存送来。

常见缓解方式包括:

方式 解决思路
缓存 在 CPU 附近放小容量高速存储
指令流水线 让多条指令处于不同执行阶段
预取 提前猜测并加载将要使用的数据
分支预测 预测跳转方向,减少流水线停顿
多级存储 用速度和容量不同的存储层次平衡成本

这也是为什么性能优化常常不是「多写几行快代码」,而是让数据更靠近 CPU、减少等待、提高局部性。

指令系统:CPU 的 API

指令系统(Instruction Set Architecture, ISA)是软件和 CPU 的接口。可以把它理解为 CPU 的 API 文档:它规定 CPU 能执行哪些命令,每条命令长什么样,操作数从哪里来。

一条指令通常包含:

部分 作用
操作码 Opcode 告诉 CPU 做什么,如加法、加载、跳转
操作数 Operand 告诉 CPU 对谁做,如寄存器、内存地址、立即数

例如:

ADD R3, R1, R2

含义是把 R1R2 中的数据相加,结果写入 R3

寻址方式

CPU 执行指令时必须知道数据在哪里,寻址方式就是找操作数的规则。

寻址方式 示例 特点
立即数寻址 MOV R1, #100 数据直接写在指令里,最快
寄存器寻址 ADD R1, R2 数据在寄存器里,速度快
直接寻址 MOV R1, [0x1000] 指令中包含内存地址
间接寻址 MOV R1, [R2] 寄存器里保存内存地址

理解寻址方式,可以帮助你理解为什么访问内存比访问寄存器慢,也能理解数组、指针、对象字段访问最终都会变成某种地址计算。

CISC 与 RISC

指令集设计有两种典型哲学:

对比项 CISC RISC
代表 x86 ARM、RISC-V
指令数量 多且复杂 少且规整
指令长度 常不固定 通常更固定
单条指令能力 更强 更简单
流水线优化 较复杂 更友好

这不是简单的谁好谁坏。x86 有庞大生态和兼容性优势,ARM 在移动设备和低功耗场景中表现突出,Apple Silicon 又证明了 RISC 架构也可以做到高性能桌面计算。

它是怎么工作的

程序运行时,代码和数据先进入内存。CPU 通过总线读取内存中的指令和数据,执行后再把结果写回寄存器、缓存、内存或外部设备。

为了平衡速度和成本,计算机使用分层存储:

寄存器
  -> CPU 缓存
  -> 内存
  -> SSD / 硬盘
  -> 网络存储

越靠近 CPU,速度越快、容量越小、成本越高。越远离 CPU,容量越大、速度越慢。

缓存有效的原因主要来自局部性原理:

  • 时间局部性:刚访问过的数据,短时间内可能再次访问。
  • 空间局部性:访问某个地址后,附近地址也可能很快被访问。

缓存命中时,CPU 可以很快拿到数据。缓存缺失时,就要去更慢的内存加载。平均访问时间可以粗略理解为:

平均访问时间 = 命中率 * 缓存访问时间 + 未命中率 * 内存访问时间

命中率的一点点变化,都可能带来明显性能差异。

总线与 I/O

CPU、内存和外设需要通过总线交换数据。

总线 作用
地址总线 CPU 指定要访问哪个地址
数据总线 CPU、内存、设备之间传输数据
控制总线 传输读写、中断、时钟等控制信号

I/O 设备访问方式也有不同层次:

方式 特点 问题
程序查询 CPU 反复轮询设备状态 浪费 CPU
中断 设备完成后通知 CPU 有中断处理开销
DMA 设备直接和内存交换数据 需要 DMA 控制器

DMA 对文件读写、网络传输、显卡数据搬运等场景都很重要。它减少了 CPU 逐字节搬运数据的负担。

流水线和冒险

流水线能提高吞吐量,但会带来冒险:

冒险类型 含义 常见处理
结构冒险 多条指令争用同一硬件资源 增加资源或暂停
数据冒险 后一条指令依赖前一条结果 数据转发、插入气泡
控制冒险 分支跳转改变执行流 分支预测、流水线清空

所以 CPU 性能不是单一主频决定的,还受缓存、流水线、分支预测、指令集、内存访问模式等多因素影响。

开发中的真实场景

组成原理在开发中经常以「性能现象」出现:

  • 同样的算法,连续数组通常比链表更容易利用 CPU 缓存。
  • 频繁磁盘 I/O 会拖慢接口响应。
  • 大文件上传下载不能一次性读入内存。
  • 数据库查询慢,可能不是业务逻辑慢,而是磁盘、索引或缓存命中问题。

AI Coding 时代怎么用

你可以要求 AI 在生成方案时说明资源使用:

  • 内存占用大概是多少?
  • 是否会产生大量磁盘 I/O?
  • 是否适合流式处理?
  • 是否有缓存友好的数据结构?
  • 这个优化是有证据,还是只是猜测?

让 AI 写代码之前先解释资源模型,能避免很多「能跑但不稳」的实现。

常见误区

误区一:认为内存和硬盘只是容量不同。它们的访问速度、使用方式和故障表现都不同。

误区二:认为 CPU 越快程序就一定越快。很多程序瓶颈在内存、磁盘、网络或锁竞争。

误区三:认为组成原理离业务开发很远。事实上,接口性能、文件处理、缓存策略都与它有关。

误区四:看到缓存就只想到 Redis。CPU 缓存、操作系统页缓存、数据库缓存、应用缓存是不同层次的缓存,但背后都有「用更近、更快的副本减少慢访问」这个思想。

小结

计算机不是一个黑盒,而是 CPU、内存、存储、I/O 和总线协作的系统。理解这些部件的速度差异和协作方式,是理解程序性能和系统行为的基础。