计算机体系结构这词儿科班出身的人都听过但真被问起什么是体系结构、什么是微架构的时候能一口气说清楚的人其实不多。更别提一堆英文缩写砸过来——ISA、IPC、TLB、ROB、MESI——每一个都像认识凑一块儿就懵。我当年啃计算机组成原理的时候就是被这些术语搞得头大后来工作了才发现不理解这些东西连排查性能问题都无从下手。这篇东西不是教科书是我自己把这些年反复用到、反复被问到的计算机体系结构相关术语按我的理解重新梳理了一遍。适合刚入门的学生、准备面试的开发者也适合那些写了几年代码但想补补底层知识的同行。我会尽量把每个术语背后的为什么要这样设计也讲清楚毕竟死记硬背没意义理解了设计动机术语自然就记住了。1. 先搞清楚体系结构、微架构、实现方式这三层关系很多人把体系结构和微架构混着用这俩区别挺大。计算机体系结构Computer Architecture指的是从程序员视角看到的机器抽象核心是指令集架构ISAInstruction Set Architecture规定了CPU支持哪些指令、寄存器怎么用、内存怎么寻址、异常怎么处理。它像是硬件的用户手册——软件只要按这套规则写就能跑在硬件上至于硬件内部怎么实现软件不关心。微架构Microarchitecture则是具体怎么实现这套ISA。同一个ISA可以有不同的微架构。比如x86指令集大家都一样但Intel的酷睿和AMD的锐龙内部流水线深度、缓存容量、乱序执行窗口大小都不同这就是微架构的差异。再往下一层是实现方式比如用多少纳米工艺、几层金属布线那是物理层面的事。我喜欢拿餐厅举例子ISA是菜单顾客软件按菜单点菜微架构是后厨的布局和设备同样一张菜单不同餐厅的后厨流程可能差别很大实现方式就是后厨装修用的材料和灶台火力大小。这个概念想通了后面所有术语都能分门别类放进去。理解这三层关系还有个实际价值面试的时候被问什么叫兼容什么叫移植你如果能从ISA和微架构的层面解释比空洞地说兼容就是能跑要专业得多。同一个ISA的软件能互相跑靠的就是体系结构层保持一致微架构随便改。2. 经典框架里的基础术语CPU、内存、总线、输入输出2.1 冯·诺依曼结构的关键角色冯·诺依曼结构Von Neumann Architecture是绝大多数通用计算机的底子核心思想就一句话存储程序——指令和数据放在同一块内存里CPU一条条取出来执行。这个结构里的基础术语每一个都得吃透CPUCentral Processing Unit中央处理器负责取指令、翻译指令、执行指令。现代CPU内部有多个核心每个核心又有多个执行单元。内存Memory存放指令和数据的存储设备。在冯·诺依曼结构里指令和数据共用一套内存空间所以也叫单一存储空间结构。总线Bus连接CPU、内存、I/O设备的公共通道。按传输内容分有地址总线Address Bus、数据总线Data Bus、控制总线Control Bus按位置分有内部总线、系统总线、外部总线。输入/输出设备I/O Devices和人或其他系统打交道的设备键盘、显示器、硬盘、网卡都属于这一类。这个结构的最大特点也是它的最大瓶颈CPU和内存之间只有一条总线指令和数据抢着用这就是著名的冯·诺依曼瓶颈。访问内存的速度跟不上CPU的运算速度CPU常常要空等。现代计算机用多级缓存来缓解这个问题但瓶颈依然存在。2.2 哈佛结构及其变体哈佛结构Harvard Architecture和冯·诺依曼结构不同它把指令存储器和数据存储器分开各自有独立的总线。好处是CPU可以在取指令的同时读写数据两个操作并行吞吐率更高。但完全的哈佛结构也有麻烦指令区不能动态写数据跑不了自修改代码这类操作。所以现实中大多数嵌入式芯片用的是改进型哈佛结构——物理上指令和数据分开但在逻辑上对软件统一编址既能并行访问又能满足灵活性。我工作中接触过的DSP芯片和MCU基本都是这种折中方案。这里有个术语细节值得注意指令缓存I-Cache和数据缓存D-Cache分离也算一种哈佛思想的体现因为现代CPU的L1缓存普遍是分开的就是为了让取指和数据访问互不干扰。2.3 时序相关术语时钟周期、机器周期、指令周期时钟周期Clock CycleCPU主时钟的一个脉冲周期是CPU工作的最小时间单位。2GHz的时钟周期就是0.5纳秒。机器周期Machine Cycle访问一次内存或完成一次总线操作所需的时间通常由几个时钟周期组成。指令周期Instruction Cycle执行一条指令的完整过程包括取指Fetch、译码Decode、执行Execute、访存Memory Access、写回Write Back等阶段。这三个周期的层级关系是时钟周期 机器周期 指令周期。理解这个层级再看后面流水线的内容会轻松很多。3. CPU内部的核心术语从算术逻辑单元到流水线3.1 CPU内部的关键部件CPU内部不只是一块芯片它是一套复杂的子系统。这些术语你必须门儿清控制单元Control Unit负责从内存取指令、译码然后产生控制信号去指挥其他部件工作。它是CPU的调度中心。算术逻辑单元ALUArithmetic Logic Unit执行加减乘除等算术运算和与或非等逻辑运算的电路。现代CPU里往往有多个ALU支持并行运算。寄存器RegisterCPU内部最快的存储单元。指令操作数、中间结果、状态标志都存在这里。常见的有程序计数器PCProgram Counter存下一条要执行指令的地址。指令寄存器IRInstruction Register存放当前正在执行的指令。累加器ACCAccumulator暂存ALU运算结果。状态寄存器/标志寄存器Flag Register记录零标志、进位标志、溢出标志等。通用寄存器GPRGeneral Purpose Register给程序员随便用的寄存器x86里就是EAX、EBX、RCX这些。译码器Decoder把二进制指令翻译成具体的控制信号。缓存CacheCPU和主内存之间的高速小容量存储后面专门讲。这些部件的连接方式也很重要。寄存器之间怎么传数据由总线或交叉开关负责运算数怎么送进ALU通过多路选择器MUX选通。每个部件都有一堆控制引脚由控制单元在节拍信号下统一驱动。3.2 流水线技术指令级并行的基石流水线Pipeline是CPU提升性能的基础手段。它把指令执行分成若干阶段让多条指令像工厂流水线一样重叠执行。经典的RISC流水线是五级IFInstruction Fetch取指IDInstruction Decode译码EXExecute执行MEMMemory Access访存WBWrite Back写回理想情况下每个时钟周期能完成一条指令吞吐量提升五倍。但实际流水线没这么美好会遇到冒险Hazard结构冒险Structural Hazard硬件资源不够两条指令同时要用同一个部件。数据冒险Data Hazard指令之间存在数据依赖后面的指令要等前面的结果。比如a b c; d a e第二条必须等第一条算完。控制冒险Control Hazard遇到分支指令不知道该取哪条指令普遍用分支预测Branch Prediction解决。流水线冲突导致的结果叫流水线停顿Stall或气泡Bubble。处理数据冒险的常见手段是转发Forwarding也叫旁路Bypass把ALU的输出直接送回给需要的指令不用等写回寄存器。控制冒险主要靠分支预测器、分支延迟槽等方式缓解。我在学这个的时候有个体会流水线的深度不是越深越好。深度越深单级延迟越短时钟频率可以更高但分支预测失败的代价也更大一旦失手整个流水线要清空重来这个损失叫流水线冲刷Pipeline Flush。所以现代CPU的深度大致在14到20级之间都是在权衡频率和分支损失后定的。3.3 乱序执行与前瞻执行乱序执行Out-of-Order ExecutionOoO是高性能处理器的标志之一。思路很简单不按程序顺序执行指令而是哪条指令的操作数齐了就先执行哪条然后再把结果按顺序提交Commit保证最终效果和顺序执行一致。这项技术背后需要一堆部件和术语支撑重排序缓冲ROBRe-order Buffer记录指令的原始顺序保证乱序执行完的结果最后能按序提交。保留站Reservation Station存放准备执行的指令和等待的操作数。寄存器重命名Register Renaming消除假数据依赖WAR和WAW hazard。物理寄存器比架构寄存器多重命名表把逻辑寄存器映射到物理寄存器上。前瞻执行Speculative Execution分支判断还没出结果就先猜一个方向执行下去猜对了效率翻倍猜错了要回滚。这里有个安全相关的话题TZ前几年闹得很大的那几个CPU漏洞都和前瞻执行有关——被称作瞬态执行攻击。具体细节不方便展开但你要明白一个道理高性能和安全性在某些场景是矛盾的这就是为什么懂体系结构的人在做安全设计时会格外小心。4. 指令集架构相关术语ISA、寻址方式、字节序4.1 ISA的大类CISC、RISC、以及现代的交融CISCComplex Instruction Set Computer复杂指令集。指令数量多、每条指令能干的事复杂一条指令可以同时完成多次内存访问和运算。代表是x86。优点是指令密度高、代码紧凑缺点是译码复杂、功耗高。RISCReduced Instruction Set Computer精简指令集。指令格式规整、长度固定、绝大多数指令在一个周期内完成寻址方式少只有LOAD/STORE指令能访问内存。代表是ARM、RISC-V、MIPS。学RISC系CPU的微架构要比学x86容易得多因为每一条指令的行为都很规整流水线设计好做。两者融合的趋势现代x86 CPU内部其实是先把复杂指令翻译成微操作Micro-Opµop再像RISC一样流水线执行。所以英文里有个说法叫CISC front-end, RISC back-end。英特尔从Pentium Pro开始就走这条路了译码器成了复杂指令集CPU里很关键的组件。4.2 指令的基本构成和寻址方式一条指令通常包含操作码Opcode和操作数Operand。操作码告诉CPU干什么操作数告诉CPU对谁干。寻址方式Addressing Mode解决的是操作数在哪里的问题。常见的几种寻址方式操作数位置典型用途立即寻址Immediate指令里直接带常量给变量赋初值寄存器寻址Register寄存器里最快最常用直接寻址Direct内存地址直接写在指令里访问全局变量间接寻址Indirect寄存器存的是内存地址指针操作基址变址寻址BaseIndex基址寄存器偏移量数组、结构体访问每条指令执行前都要先取操作数如果能从寄存器里拿就直接拿如果要去内存拿就会慢因为要等待访存返回。这也是RISC设计里LOAD/STORE架构的一个原因——把访存操作单独剥离出来让普通运算指令不要间接卡在内存延迟上。4.3 字节序与对齐字节序Byte Order是个容易踩坑的术语尤其在多机通信和二进制协议打交道的时候大端Big-Endian高位字节在低地址。看起来像人类读数字的顺序。小端Little-Endian低位字节在低地址。x86和大多数ARM都是小端。同一个32位数0x12345678在内存里按大端存是12 34 56 78按小端存是78 56 34 12。我当年写串口协议解析时因为收发双方字节序不一致折腾了两天才排查出来。所以看到任何二进制协议第一件事永远是确认字节序。还有个数据对齐Alignment的概念。CPU访问内存时如果数据地址不是其大小的倍数比如4字节的int地址不是4的倍数可能产生未对齐访问Misaligned Access。有些CPU直接报异常有些CPU要分多次访问再拼接性能损耗严重。编译器通常会自动做对齐但手动处理缓冲区时就得注意了。4.4 其他指令级术语Pipelined and Multi-cycle多周期指令在一个周期里只完成一部分工作需要多个周期才能完成整条指令。向量指令SIMD单条指令同时处理多个数据。x86里的MMX、SSE、AVXARM里的NEON都是SIMD扩展。对应的是标量指令Scalar一次处理一个数据。异常Exception和中断InterruptCPU执行指令时检测到的内部错误或外部事件。区别在于异常由当前指令触发比如除零非法指令中断来自外部设备。处理流程一样先保存现场上下文再跳到对应的处理程序处理完恢复现场。涉及的概念包括中断向量表、中断优先级、嵌套中断、屏蔽Mask等。5. 存储系统中的术语从寄存器到磁盘一个都不能少5.1 存储层次设计动机存储系统的设计动机很简单快和便宜不可兼得。寄存器和缓存快但容量小成本高磁盘容量大成本低但是比寄存器慢上百万倍。解决思路就是做层次化存储Memory Hierarchy让常用的数据待在快的层次里不常用的沉到慢的层次里去。层次从快到慢依次是寄存器 → L1缓存 → L2缓存 → L3缓存 → 主内存RAM → SSD → 机械硬盘。每往下一层容量大约大一个数量级速度大约慢一个数量级每字节成本大约便宜一个数量级。程序性能好不好很大程度上取决于它能不能把热数据留在高层。5.2 缓存机制术语操作系统和CPU打交道最多的就是缓存这些术语必须特别清楚缓存命中Cache Hit要的数据在缓存里直接返回快。缓存未命中Cache Miss数据不在缓存里要去下一层拿。拿回来后通常会把数据填进缓存这就涉及缓存替换策略。缓存行Cache Line缓存和内存之间交换数据的最小单位通常64字节。所以即使你只想读一个字节CPU也会把整条缓存行的64字节都加载进来利用空间局部性预取更多数据。映射方式直接映射Direct-Mapped每个内存块只能映射到唯一的缓存行。全相联Fully Associative内存块可以放到任何缓存行。组相联Set-Associative折中方案把缓存分成若干组每个内存块可以映射到指定组的任意一行。替换策略LRULeast Recently Used最近最少使用、FIFO、随机替换等。写策略写直达Write-Through写缓存的同时写内存简单但慢。写回Write-Back只写缓存标记脏位Dirty Bit等缓存行被换出时才写回内存快但复杂。多核处理器还有缓存一致性Cache Coherence问题两个核各自缓存了同一内存地址的数据一个改了另一个怎么知道经典的解决方案是缓存一致性协议最知名的是MESI协议。MESI把缓存行状态分成四种状态含义MModified本核修改过与内存不一致EExclusive只被本核缓存与内存一致SShared被多个核缓存与内存一致IInvalid无效缓存行一个核修改数据时要向其他核发**失效Invalidate**消息其他核收到后把自己的副本标记为I。这样所有核读到的数据始终一致。这套东西在面试里出现的频率相当高。缓存还有个反直觉的现象叫伪共享False Sharing两个线程操作的变量在物理上位于同一条缓存行。即使逻辑上无冲突一个线程写A变量会让持有B变量的另一核的缓存行失效导致性能骤降。我在写并发代码时在关键结构体字段之间插入padding就是为了避免这个问题实测性能提升很明显。5.3 虚拟内存与MMU/TLB现代操作系统都跑在虚拟地址Virtual Address之上。CPU拿到的地址不是物理地址而是虚拟地址翻译成物理地址的工作由一个叫**MMUMemory Management Unit**的硬件单元完成。虚拟内存的核心机制是分页Paging地址空间按固定大小划分成页Page物理内存也按同样大小划分成页框Page Frame虚拟页和物理页框通过**页表Page Table**建立映射。访问页表本身也很耗时所以CPU又加了一层快表——TLBTranslation Lookaside Buffer缓存最近用过的虚拟页到物理页的翻译结果。TLB命中的话几乎没有额外开销TLB没命中就要走内存里的页表性能损耗很大。还有几个关联术语页缺失/缺页Page Fault访问的虚拟页面没有映射到物理内存触发异常由操作系统从磁盘换入。写时复制Copy-on-WriteCOWfork子进程时先共享物理内存等某个进程要写时才复制页面省内存。内存保护Memory Protection页表项里有读/写/执行权限位CPU在访问时检查权限违反则触发保护异常。缓冲区溢出漏洞的硬件基础就在这里。原子操作Atomic Operation不可被中断的操作比如Compare-And-SwapCAS。多线程同步、无锁数据结构全都依赖它。在CPU层面它往往由一个内嵌锁定前缀的总线操作或硬件事务内存HTM来完成。6. 性能衡量术语时钟频率、IPC、延迟与吞吐量衡量一台计算机快不快不能只看主频。曾经有段时间厂商喜欢宣传GHz数字搞得大家以为主频高就等于快实际上同样是3GHz的CPUIPC可能差一大截。这些参数你需要分开理解时钟频率Clock Frequency每秒钟的时钟周期数单位Hz。3GHz表示每秒钟30亿个时钟周期。CPICycles Per Instruction平均每条指令需要的时钟周期数。IPCInstructions Per Cycle每个时钟周期完成的指令数是CPI的倒数。IPC越高越好是现代CPU微架构性能的核心指标。MIPSMillion Instructions Per Second每秒执行的百万条指令数。MIPS 主频 × IPC ÷ 1000000。延迟Latency单个请求从发出到完成的时间。比如内存访问延迟约100纳秒。吞吐量Throughput单位时间内完成的请求数量。比如每秒处理多少条指令。延迟和吞吐量是两个维度提升一个不代表提升另一个。某个操作延迟很高但很多操作可以并行进行吞吐量照样很高。流水线和超标量就是这么拼吞吐量的。还有一条很经典的设计法则要掌握Amdahl定律阿姆达尔定律。它说的是系统加速比取决于被加速部分在总耗时中的占比。公式是加速比 1 / ((1 - P) P/S)其中P是可并行化部分占比S是该部分的加速倍数。如果P只有50%无论这部分加速到无穷快整体加速比也到不了2倍。这个定律解释了为什么优化要抓主要矛盾也解释了木桶效应在性能工程里的含义。7. 多处理器与并行体系结构术语7.1 从单核到多核单核性能提升遇到功耗墙Power Wall之后CPU厂商转向了多核路线。这样就有了这些术语多核处理器Multi-core Processor一个芯片上集成多个处理器核心。核之间共享部分缓存和内存控制器。SMPSymmetric Multi-Processing对称多处理多个处理器或多个核心对内存访问是平等的每个核访问内存的延迟基本相同。本质上是UMAUniform Memory Access统一内存访问。NUMANon-Uniform Memory Access非统一内存访问在多路服务器里每个CPU节点有自己的本地内存访问本地内存比访问远端内存快。Linux性能调优里经常要绑核CPU Affinity和指定numactl参数就是为了让线程用上本地内存。锁Lock与同步原语多核之间竞争资源时要互斥。术语包括互斥锁Mutex、自旋锁Spinlock、读写锁RWLock、信号量Semaphore、屏障Barrier。理解NUMA还有个实际收益在高并发服务器上同样的代码绑不绑核、内存在不在本节点性能能差出百分之几十。性能测试报告里如果没注明NUMA策略参考价值会大打折扣。7.2 并行计算的分类Flynn分类法计算机体系结构教科书里必提的Flynn分类法按指令流和数据流把计算机分成四类分类含义典型SISD单指令流单数据流传统单核CPUSIMD单指令流多数据流向量处理器、GPUMISD多指令流单数据流几乎无实用系统只在容错机中出现过MIMD多指令流多数据流多核CPU、集群我们平时写代码时用SIMD库去做向量化就是在利用SIMD开多线程跑不同任务属于MIMD多台机器组成分布式集群也是MIMD的粗粒度版本。GPU的大规模并行靠的是几千个简单的核同时做SIMD类型的运算。7.3 多核之间的通信与连线多核不是简单地把几个CPU拼在一起它们之间怎么通信是个大问题。常见的方式总线连接Bus所有核挂到一条共享总线上简单但容易成为瓶颈。交叉开关Crossbar每个核到内存都有专用通路速度快但硬件成本高。片上网Network-on-ChipNoC现代大型CPU把裸芯内部做成一个小网络数据按数据包方式在各节点之间路由传输扩展性好。这些连接结构的性能受很多细节影响包括路由算法、缓冲区深度、仲裁策略等。做嵌入式和高性能计算的人迟早会碰到这些术语。8. 面试和实战中极易混淆的术语对照表我整理了这些年工作中和面试里反复出现的易混淆术语。这四组我ir是真正问倒过人的放一起对比就清楚了易混淆术语组一句话区分ISA vs 微架构ISA是软件看到的抽象接口微架构是接口的具体实现延迟 vs 吞吐量延迟是单次操作的时间吞吐量是单位时间完成的次数二者可以独立变化缓存命中率 vs 命中时间前者看运气好不好后者看命中后拿数据快不快优化手段完全不同UMA vs NUMAUMA里所有内存延迟一样NUMA里本地快远端慢大端 vs 小端大端高位在低地址小端低位在低地址虚拟地址 vs 物理地址CPU发出的地址要经过MMU翻译才能真正访问内存还有一个我特别想强调的坑时钟频率提升一倍性能提升一倍是错的。性能是主频、IPC、内存延迟、缓存命中率、并行程度共同作用的结果。主频只是其中一个因子而且提升主频往往意味着更深流水线和更多等待周期。9. 想彻底掌握这些术语我推荐的路径最后聊聊我自己的学习路径仅供参考。我觉得术语这东西靠背单词表真的记不住得靠动手和内化。第一个阶段是硬啃一本经典的教材。我用的是《计算机组成与设计》和《计算机体系结构量化研究方法》Hennessy和Patterson那套。这两本读下来绝大多数术语都有了解。读的时候不用逐字只需要把章节里关键术语部分过一遍遇到不懂的在旁边标注。第二个阶段是结合反汇编去理解ISA和寄存器。拿Linux下的objdump把自己编译的一个简单C程序反汇编逐个看生成的指令长什么样对照指令集手册看每条指令的操作数怎么编码、寻址方式是什么。这个过程非常有效因为你亲眼看到了寄存器如何被压栈、弹栈看到了栈帧怎么建立和销毁。第三个阶段是看CPU性能计数器跑真实负载。用perf stat跑一个程序看看IPC、缓存未命中率、分支预测失败率这些数字再回去调代码对比调整前后的数据变化。很多术语在这个阶段从书上的定义变成了我能感知的现象。给新手的建议很简单每接触一个新术语问自己三个问题——它解决什么问题如果不这么设计会怎样它在实际系统里对应哪个部件或者哪个数字把这套自问自答想通了术语就不再是死记硬背的外语单词而是你理解计算机内部构造的砖瓦。我个人反复体会最深的一点是体系结构的术语大多是成串出现的把每个术语放进存储层次指令流水线并行处理多处理器互联这几个大框架里去理解你会发现它们之间是相互关联的记忆效率会高非常多。希望你读完这篇之后下次再看到那些字母缩写时脑子里浮现的不再是陌生感而是一个清晰的系统图景。