Skip to content

AMD Zen微架构

2012年,AMD的股价跌至1.62美元,市值缩水到不足20亿美元——不到Intel的2%。Bulldozer架构的CMT(Cluster Multi-Threading)策略被证明是一场灾难:两个"核心"共享一个浮点单元和前端解码器,单线程IPC比Intel Sandy Bridge低约40%。在SPEC CPU 2006上,Bulldozer FX-8150的单线程性能甚至不如三年前的Phenom II X4。分析师普遍预测AMD将在两到三年内破产或被收购。就在这个至暗时刻,Jim Keller——曾主导Alpha 21264(第 40.0 章)和AMD K8(第一个x86-64处理器)设计的传奇架构师——于2012年重返AMD,领导一个全新微架构的开发。四年后,Zen微架构的诞生证明了这可能是处理器设计史上最伟大的绝地反击。

Zen的成功从根本上验证了本书的核心论点:处理器设计的本质是在有限的晶体管预算和功耗约束下,通过投机和并行的层层叠加来逼近指令吞吐率的理论上限。Bulldozer的失败在于它选择了错误的并行维度——以CMT追求线程级并行,却牺牲了单线程IPC这一基础。Zen的成功在于它回归了正确的优先级:首先确保竞争力的单线程IPC(通过独立的宽前端、大ROB和丰富的执行资源),然后在此基础上通过SMT、Chiplet和Infinity Fabric逐步叠加更高层次的并行。这种"先深后宽"的设计哲学贯穿了从Zen 1到Zen 5的五代演进,每一代在流水线宽度/深度(第 2.0 章)、微操作缓存(第 23.0 章)、片上互连(第 47.0 章)和Chiplet封装(第 52.0 章)等维度上持续优化。

从微架构设计的角度来看,Zen系列的成功包含多个层面的创新。在核心微架构层面,Zen彻底抛弃了Bulldozer的CMT理念,回归了传统的SMT设计,并构建了一个全新的4-wide解码、6-wide发射的高性能乱序核心。在片上互连层面,Zen引入了Infinity Fabric——一种基于HyperTransport演进的高带宽、低延迟片上互连协议,使得多核之间、多Die之间的通信效率大幅提升。在封装架构层面,从Zen 2开始采用的Chiplet设计——将计算Die(CCD)和I/O Die(IOD)分离制造——成为半导体产业中Chiplet架构的标杆案例,深刻影响了整个行业的芯片设计方法论。

本章将从四个维度深入分析AMD Zen微架构家族。第一节对Bulldozer的失败进行定量分析,从第一性原理解释CMT为何不如SMT。第二节聚焦于Zen 1的核心设计突破,包括解码流水线、微操作缓存、CCX结构和Infinity Fabric互连。第三节讨论Zen 4和Zen 5的关键演进,涵盖前端扩展、后端加宽、AVX-512支持策略以及分支预测器的代际升级。第四节深入分析EPYC服务器处理器的Chiplet架构设计,包括CCD+IOD的组织方式、多Die之间的缓存一致性协议以及内存控制器的布局策略。

Bulldozer失败的定量分析

在分析Zen 1的设计之前,必须首先理解Bulldozer为何失败——因为Zen 1的几乎每一个设计决策都是对Bulldozer某个具体缺陷的直接回应。Bulldozer的失败不是某个单一设计错误的结果,而是其核心设计哲学——CMT(Cluster Multi-Threading)——在实际工作负载面前的系统性崩溃。

CMT vs SMT vs 独立核心的第一性原理分析

处理器设计中增加多线程能力有三种基本策略,每种策略对晶体管预算的分配方式根本不同:

独立核心(CMP, Chip Multi-Processing):完全复制整个核心,包括前端、后端和所有Cache。面积成本为N×AcoreN \times A_{\text{core}}NN个核心,每个面积AcoreA_{\text{core}})。每个线程获得完整的核心资源,单线程IPC最高。但面积效率最低——在面积预算固定时,核心数量最少。

SMT(Simultaneous Multi-Threading):在一个核心内部复制少量状态(PC、RAT快照、部分队列分区),共享大部分执行资源(执行端口、Cache、ROB的大部分容量)。面积成本约为Acore×1.05A_{\text{core}} \times 1.05(SMT的额外面积开销约5%)。单线程IPC接近独立核心(仅因共享资源的争用损失约5%\sim10%),但在多线程场景下可以将单核吞吐提升30%\sim40%。

CMT(Cluster Multi-Threading,Bulldozer的方案):在独立核心和SMT之间的折中——每个"模块"包含两个"核心",各自拥有独立的整数执行单元和L1 DCache,但共享前端解码器、浮点/SIMD单元和L2 Cache。面积成本约为Acore×1.6A_{\text{core}} \times 1.6(一个CMT模块提供两个"核心",但面积约为两个独立核心的80%)。

设计权衡 1 — CMT vs SMT vs 独立核心的资源效率

策略面积/线程单线程IPC多线程吞吐面积效率
独立核心1.00×A1.00 \times A1.00×\timesN×1.00N \times 1.00基准
SMT (2-way)0.53×A0.53 \times A0.92×\times1.35×1.35 \times最高
CMT (Bulldozer)0.80×A0.80 \times A0.60×\times1.50×1.50 \times

CMT的致命问题在表中一目了然:虽然多线程吞吐量略高于SMT(1.50×\times vs 1.35×\times),但单线程IPC降低了40%(0.60×\times vs 0.92×\times)。在实际工作负载中,大量应用(桌面软件、游戏、Web浏览)对单线程性能极为敏感,40%的IPC损失使Bulldozer在这些场景中完全不具竞争力。更糟的是,CMT的面积效率也不如SMT——0.80A0.80A/线程 vs 0.53A0.53A/线程。CMT试图在两个维度之间折中,结果在两个维度上都不如对手。

Bulldozer的具体微架构缺陷

缺陷1:共享前端的带宽腰斩。Bulldozer的4-wide解码器在两个整数核心之间共享。在单线程模式下,虽然单线程理论上可以使用全部4-wide带宽,但解码器的仲裁逻辑和线程切换开销使实际可用带宽约为3\sim3.5条指令/周期。在双线程模式下,每个核心的有效解码带宽降至2-wide——这在2011年就已经是不可接受的窄度。作为对比,Intel Sandy Bridge(同年发布)的每个核心拥有独立的4-wide解码器,即使在HT(SMT)模式下每个线程的有效解码带宽仍约为3\sim3.5-wide。

缺陷2:共享FPU的瓶颈。Bulldozer的两个核心共享一个128位浮点/SIMD单元。执行256位AVX指令需要2个周期(128位×\times2),且两个核心轮流使用。在浮点密集的SPEC CPU fp基准上,Bulldozer的性能只有Sandy Bridge的50%\sim60%。更严重的是,即使只有一个核心在运行FP代码,它也无法获得FPU的全部带宽——FPU的仲裁逻辑引入了1\sim2周期的额外延迟。

缺陷3:L2 Cache争用。两个核心共享2MB L2 Cache。当两个核心运行不同程序时,工作集在L2中相互驱逐。AMD内部测量显示,双线程场景下L2有效容量降至标称的60%\sim70%。

缺陷4:SPEC CPU 2006的定量差距。

案例研究 1 — Bulldozer vs Sandy Bridge: SPEC CPU 2006定量对比

以下数据来自实际测量(归一化到相同频率下的IPC):

基准子集Bulldozer IPCSandy Bridge IPC差距
SPECint2006 (单线程)1.00×\times1.42×\times-30%
SPECfp2006 (单线程)1.00×\times1.67×\times-40%
SPECint2006_rate (多线程)1.00×\times1.15×\times-13%
SPECfp2006_rate (多线程)1.00×\times1.25×\times-20%

两个关键观察:(1)单线程差距(30%\sim40%)远大于多线程差距(13%\sim20%),证明CMT在多线程场景下确实缩小了差距,但代价是严重牺牲单线程性能;(2)FP差距(40%单线程、20%多线程)大于INT差距(30%单线程、13%多线程),直接反映了共享FPU的瓶颈效应。

为什么CMT失败而SMT成功?根本原因在于资源共享的粒度。SMT在微操作级别共享资源——两个线程的微操作在同一个调度器中按数据就绪顺序动态竞争执行端口,粒度极细。这种细粒度共享意味着当一个线程因Cache miss阻塞时,另一个线程可以立即使用空闲的执行端口——资源利用率接近100%。而CMT在"核心"级别共享资源——每个核心有自己的整数执行端口,不能被另一个核心使用。当一个核心阻塞时,它的整数执行端口空闲浪费,但另一个核心无法借用。CMT的共享粒度太粗,导致资源利用率在单线程场景下远低于独立核心或SMT。

Zen 1的设计突破

Zen 1微架构的设计始于2012年前后,由Jim Keller领导的团队在AMD奥斯汀设计中心开发。其设计目标非常明确:在保持面积和功耗竞争力的前提下,实现相对于Excavator微架构40%以上的IPC提升。最终发布的Zen 1在14nm FinFET工艺(GlobalFoundries 14LPP)上实现了这一目标,并在多项基准测试中达到了与Intel Skylake相当的单线程性能——这在当时被认为几乎是不可能的。

理解Zen 1的设计突破,需要首先回顾Bulldozer微架构的关键缺陷。Bulldozer采用了CMT(Clustered Multi-Threading)架构,两个"核心"共享一个前端(取指和解码单元)、一个浮点单元和L2 Cache,每个核心独立拥有整数执行单元和L1数据Cache。这种设计的初衷是以较低的面积代价提供多线程能力,但实际效果却是:共享的前端成为严重瓶颈,每个整数核心只有一个128位的浮点/SIMD通路,而且共享L2的争用导致访存延迟显著增加。Bulldozer的解码器宽度为4条x86指令/周期,但由于两个整数核心共享这个解码器,每个核心的实际解码带宽仅为2条指令/周期——这在当时是极为狭窄的。

硬件描述 1 — Bulldozer CMT架构的失败教训

Bulldozer的CMT设计失败提供了多条对Zen 1至关重要的设计教训。逐一分析这些教训,有助于理解Zen 1为何做出特定的设计选择。

教训1:共享前端的代价远超预期。Bulldozer的两个整数核心共享一个4-wide解码器,初衷是节约面积(一个解码器替代两个)。然而实际效果是:(1)每个核心的解码带宽被腰斩为2-wide,在单线程场景下成为严重瓶颈;(2)即使在双线程场景下,4-wide的总解码带宽也不足以喂饱两个核心的执行资源;(3)两个核心竞争共享前端造成了额外的仲裁延迟和气泡。Zen 1的应对:每个核心拥有完全独立的4-wide解码器,即使在面积上多花了一倍的前端成本,也确保每个核心在单线程模式下获得全部的解码带宽。

教训2:浮点/SIMD共享导致严重瓶颈。Bulldozer的两个核心共享一个128位的浮点/SIMD单元。在当时AVX已经引入256位操作的背景下,Bulldozer通过128位通路执行256位指令需要2个周期。更糟糕的是,两个核心必须轮流使用这个共享单元。在浮点/SIMD密集的工作负载中(如科学计算、多媒体处理),Bulldozer的性能远落后于Intel的Sandy Bridge。Zen 1的应对:每个核心拥有独立的浮点/SIMD单元,包含2个128位FMAC单元,可以拼合执行256位AVX2操作,在面积和功耗上取得了合理的平衡。

教训3:共享L2 Cache引入的争用效应。Bulldozer的两个核心共享2MB L2 Cache。当两个核心运行不同的程序时,各自的工作集在L2中相互驱逐(thrashing),导致L2命中率严重下降。AMD的测量表明,在多线程场景下Bulldozer的有效L2容量仅约为标称容量的60%–70%。Zen 1的应对:每核私有512KB L2 Cache,完全消除了核间L2争用。虽然每核的L2容量从1MB(共享2MB的一半)降低到512KB,但由于消除了争用效应,有效容量反而更大。

教训4:CMT在操作系统调度中的混乱。操作系统将Bulldozer的每个整数核心视为一个独立的逻辑处理器,但实际上它们共享大量资源。这导致了调度器的困惑——操作系统可能将两个不相关的线程分配到同一个CMT模块的两个核心上,导致严重的资源争用;或者在只有一个活跃线程时,操作系统不知道该线程无法获得全部的浮点和L2资源。Windows和Linux都需要为Bulldozer编写专门的调度器补丁。Zen 1的应对:回归标准SMT模型,操作系统可以使用成熟的SMT调度策略,不需要专门的硬件感知补丁。

教训5:过度追求多线程而忽视单线程。Bulldozer的设计理念是"以面积换线程数"——在相同面积下提供更多的硬件线程来提升多线程吞吐量。然而,大量的实际应用(如桌面软件、游戏、Web浏览)对单线程性能非常敏感。当Bulldozer的单线程IPC远低于Intel竞品时,多线程优势无法弥补单线程的劣势。Zen 1的应对:首先确保竞争力的单线程IPC(通过独立的宽前端、大ROB和丰富的执行资源),然后在此基础上通过SMT提供多线程能力。

Zen 1从根本上抛弃了CMT架构,回归了每个核心拥有完整、独立前端和后端的传统设计。每个Zen 1核心包含一个独立的4-wide解码器、一个独立的微操作缓存(Op Cache)、独立的整数和浮点/SIMD执行单元,以及独立的L1指令Cache和L1数据Cache。两个硬件线程通过SMT(Simultaneous Multi-Threading)共享核心资源,但每个线程都能获得远超Bulldozer的单线程性能。

解码与微操作缓存

x86指令集的变长编码一直是处理器前端设计的主要挑战。x86指令的长度从1字节到15字节不等,前缀字节(prefix)、操作码(opcode)、ModR/M、SIB、位移(displacement)和立即数(immediate)等字段的组合使得指令边界的确定变得十分复杂。Zen 1的前端流水线必须在有限的周期数内完成从I-Cache取指到微操作送入后端的全过程,其设计在多个层面体现了精巧的工程权衡。

取指阶段。Zen 1的L1指令Cache为64KB、4路组相联、64字节Cache行。每周期从I-Cache取出一个32字节的取指窗口(fetch window),送入指令字节缓冲区(Instruction Byte Buffer)。32字节的取指宽度意味着在最好情况下(所有指令为最短的1字节编码),一次取指可以覆盖32条指令;在典型的x86代码中(平均指令长度约4–5字节),一次取指覆盖约6–8条指令,足以满足4-wide解码器的需求。

指令预解码与标记。在指令进入I-Cache之前(即I-Cache的填充路径上),Zen 1对指令字节进行预解码(pre-decode),为每个字节附加标记位(mark bits),标识指令的起始位置、结束位置以及该指令是否需要分解为多条微操作。这些标记位与指令字节一起存储在I-Cache中,使得后续的解码阶段可以快速确定指令边界,无需重新扫描整个取指窗口。预解码的代价是增加了I-Cache的有效存储宽度(每字节额外存储2–3位标记),但显著简化了主解码器的逻辑复杂度。

解码器组织。Zen 1配备了4个并行的x86解码器,每周期最多解码4条x86指令。其中:

  • 4个解码器均为复杂解码器(complex decoder),每个解码器都能处理1–2条微操作的指令。这与Intel的设计形成对比——Intel从Sandy Bridge到Skylake采用的是"1个复杂解码器+3/4个简单解码器"的非对称配置,其中简单解码器只能处理单微操作指令。

  • 对于需要分解为3条及以上微操作的复杂x86指令(如REP MOVS、某些带有锁前缀的读-改-写指令),使用微码ROM(Microcode ROM)进行展开。微码ROM的入口在解码阶段被触发,微码引擎接管前端,逐周期产生微操作序列。

  • 解码器每周期最多产生8条微操作(macro-ops),送入微操作队列(Micro-Op Queue)。

设计提示

Zen 1选择4个对称的复杂解码器而非Intel风格的非对称解码器配置,有其深层的设计考量。非对称解码器的问题在于:如果连续出现多条双微操作指令(如带有内存操作数的ALU指令),只有一个复杂解码器能够处理,其余3个简单解码器必须等待,有效解码带宽大幅下降。Zen 1的对称设计避免了这一问题,但代价是每个解码器的面积和复杂度更高。这一选择反映了AMD对x86指令混合特征的深入分析——在实际工作负载中,双微操作指令的比例可达20%–30%,对称解码器在平均解码吞吐量上具有显著优势。

微操作缓存(Op Cache)。Zen 1引入了微操作缓存(Op Cache,也称μ\muOp Cache),这是Zen相对于Bulldozer系列最重要的前端改进之一。Op Cache位于解码器之后、微操作队列之前,缓存已经解码好的微操作,使得热点代码路径可以绕过取指和解码阶段,直接从Op Cache获取微操作。

Zen 1的Op Cache容量为2048条微操作,组织为64组(set)×\times 8路(way)。每个Cache行最多存储8条微操作,但这些微操作必须来自同一个32字节对齐的取指窗口内的连续指令。Op Cache使用指令的PC(程序计数器)进行索引和标签匹配,命中时每周期可以输出最多8条微操作——是解码器最大吞吐量的一倍。

硬件描述 2 — Op Cache的工作机制

Op Cache的填充(fill)发生在指令被解码器处理之后:解码器产生的微操作被同时写入微操作队列和Op Cache。填充时,微操作按照其来源的x86指令的PC进行组织——同一个32字节取指窗口内的指令被映射到同一个Cache行。

Op Cache的查找(lookup)与I-Cache的取指并行发起:取指单元在向I-Cache发送取指请求的同时,也用相同的PC查询Op Cache。如果Op Cache命中,取指和解码流水线被旁路,微操作直接从Op Cache送入微操作队列;如果Op Cache未命中,则走正常的I-Cache取指和解码路径。

由于Op Cache每周期可以输出8条微操作,而正常解码路径每周期最多输出8条微操作(4条x86指令各产生1–2条微操作),Op Cache在大多数情况下能够提供更高或至少相等的微操作吞吐量。更重要的是,Op Cache消除了指令解码的延迟——在正常解码路径中,从I-Cache读取到微操作进入队列需要3–4个流水级,而Op Cache命中时只需要1–2个流水级。这一延迟缩减直接减少了分支预测失败的惩罚周期。

Op Cache的容量演进与组织优化。从Zen 1到Zen 5,Op Cache的容量经历了显著增长,同时组织方式也不断优化以提高有效利用率:

参数Zen 1Zen 2/3Zen 4Zen 5
容量(μ\muop表项数)204840966750>>6750
组织方式(组×\times路)64×864 \times 864×864 \times 8改进改进
每路最大μ\muop数888–98–9
读取带宽8 μ\muop/cyc8 μ\muop/cyc9 μ\muop/cyc>>9 μ\muop/cyc
映射窗口大小32B32B64B64B

Zen系列Op Cache容量与组织的演进

Zen 2/3的Op Cache倍增。Zen 2将Op Cache从Zen 1的2048项翻倍到4096项。这一倍增不仅仅是简单地增加存储容量——AMD同时优化了Op Cache的映射算法,改善了Way分配效率。在Zen 1中,一个32字节的取指窗口内的所有μ\muops必须映射到同一组的连续Way中。如果一个32字节窗口产生了9个μ\muops(超过了每Way 8个的限制),需要使用2个Way来存储,第二个Way只有1个μ\muop,利用率仅12.5%。

Zen 2通过改进Way分配策略来提高利用率——允许同一组内来自不同取指窗口的μ\muops更灵活地共享Way资源,减少了Way浪费。据微架构分析估计,Zen 2的Op Cache有效利用率从Zen 1的约70%提升到约78%,使得4096项的名义容量提供了约3196项的有效容量(vs Zen 1的约1434项有效容量),有效容量增长了约2.2倍。

Zen 4的进一步优化。Zen 4的Op Cache增长到6750项,同时可能将映射窗口从32字节扩大到64字节。更大的映射窗口意味着一个Op Cache行可以覆盖更长的连续代码段,减少了因窗口边界截断导致的Way浪费。64字节映射窗口在大多数工作负载中可以覆盖12–16条x86指令,几乎总是能包含一个完整的基本块(basic block)。

性能分析 1 — Op Cache命中率对不同工作负载的影响

Op Cache的命中率对性能的影响因工作负载而异:

  • 紧凑循环(如DGEMM、FFT):Op Cache命中率接近100%。循环体的μ\muop数通常远小于Op Cache容量,一旦填充后就持续命中。Op Cache的收益主要来自消除解码延迟和降低前端功耗。

  • 中等代码足迹(如SPEC CPU整数基准):Op Cache命中率约为70%–90%。热点函数和循环在Op Cache中命中,但非热点代码路径(如错误处理、初始化)可能miss。Zen 4的6750项Op Cache相比Zen 1的2048项,可以将命中率从约75%提升到约88%,对应IPC改善约5%–8%。

  • 大代码足迹(如数据库引擎、JIT编译器输出):Op Cache命中率可能低于50%。这类工作负载的活跃代码区域分散且庞大,即使6750项的Op Cache也无法覆盖。在这种场景下,传统解码路径的优化(如对称解码器、宏融合)更为重要。

AMD通过持续增大Op Cache容量来提升命中率,但容量增长受到面积和功耗的限制。Op Cache的每个μ\muop表项约需80–100位存储,6750项Op Cache的总存储量约为6750×90=607,5006750 \times 90 = 607{,}500\approx75KB——这在5nm工艺下是可接受的面积开销,但继续增大到10K+项需要仔细评估边际收益。

微操作队列与宏融合。Zen 1在解码阶段还实现了宏融合(macro-fusion):将相邻的比较/测试指令和条件跳转指令融合为一条微操作。例如,CMP rax, rbx 后紧跟 JE target 可以融合为一条"比较并跳转"微操作。宏融合有效地增加了前端的实际处理带宽——融合后的指令对只占用一个解码器槽位和一个ROB表项,使得有效指令窗口更大。

解码器和Op Cache产生的微操作进入微操作队列(Micro-Op Queue,也称Instruction Dispatch Queue),该队列同时起到解耦缓冲的作用,将前端的取指/解码与后端的重命名/分发在时间上解耦。当前端因为I-Cache缺失或解码瓶颈暂时停滞时,后端可以继续消耗队列中已有的微操作;反之,当后端因为资源不足而暂停分发时,前端可以继续解码并填充队列。

表 42.2汇总了Zen 1前端流水线的关键参数。

参数规格
L1 I-Cache64 KB, 4路, 64B行
取指宽度32字节/周期
解码宽度4条x86指令/周期
解码器类型4个对称复杂解码器
最大微操作/周期(解码)8条
Op Cache容量2048条微操作
Op Cache组织64组 ×\times 8路
Op Cache吞吐最多8条微操作/周期
宏融合支持(CMP/TEST + Jcc)
分支预测器基于感知机的混合预测器
BTB多级BTB

Zen 1前端流水线关键参数

SMT的实现细节。Zen 1支持2-way SMT,即每个物理核心可以同时执行两个硬件线程。SMT的实现要求前端和后端的多种资源在两个线程之间进行分区(partitioned)或竞争共享(competitively shared):

  • 分区资源:ROB表项在两个线程之间静态分区——每个线程获得96个ROB表项(总共192个的一半)。这种静态分区避免了一个线程因为指令执行缓慢而耗尽所有ROB表项、导致另一个线程完全饿死的情况。类似地,Load Queue和Store Queue也按线程分区。

  • 竞争共享资源:整数和浮点调度器的表项在两个线程之间动态竞争共享——调度器不区分指令来自哪个线程,先到先得。这种设计允许负载不均衡时,繁忙的线程获得更多的调度器资源。L1 I-Cache、L1 D-Cache、L2 Cache和L3 Cache也是竞争共享的。

  • 复制资源:每个线程拥有独立的体系结构状态——包括通用寄存器的映射表(RAT)、程序计数器(PC)和系统寄存器。前端的分支预测器状态也按线程维护独立的历史,避免一个线程的分支模式污染另一个线程的预测器训练结果。

  • 物理寄存器文件:物理寄存器文件的表项在两个线程之间动态竞争共享,不做静态分区。

在SMT开启时,每个线程可以交替地向解码器和Op Cache提交取指请求。Zen 1采用了轮转(round-robin)与优先级(priority)混合的SMT调度策略:在两个线程都有工作要做时,前端在每个周期交替服务两个线程的取指请求;当一个线程因Cache缺失或分支预测失败而暂停时,另一个线程可以获得全部的前端带宽。这种动态调度确保了单线程场景下的全部性能不受SMT机制的影响。

乱序后端概览。Zen 1的后端是一个完整的乱序执行引擎,其关键规格如下:

  • 重命名/分发宽度:每周期最多6条微操作(6-wide dispatch)。注意解码器是4-wide,但Op Cache可以提供最多8条微操作/周期,经过微操作队列的缓冲后,后端以6-wide进行分发。

  • ROB:192表项。作为对比,Intel Skylake的ROB为224表项。

  • 整数调度器:84表项的统一调度器(Unified Scheduler),连接到6个整数执行端口——4个ALU端口(其中2个可执行乘法)、2个AGU(地址生成单元)端口。

  • 浮点/SIMD调度器:96表项,连接到4个浮点/SIMD执行端口——2个FMAC(浮点乘加)单元、2个FADD/转换/移动单元。

  • 物理寄存器文件:168个整数物理寄存器,160个浮点/SIMD物理寄存器。

  • L1 D-Cache:32 KB, 8路, 64B行, 4周期延迟。支持每周期2次Load + 1次Store的并发访问(2读1写端口)。

  • L2 Cache:512 KB/核, 8路, 64B行, 12周期延迟。L2采用写回(write-back)策略和非包含(non-inclusive)的L1关系。

  • Load Queue:44表项;Store Queue:44表项。

  • 提交宽度:每周期最多提交8条微操作(8-wide retire)。提交宽度大于分发宽度,确保ROB的排空速度不会成为吞吐瓶颈。

图 42.1展示了Zen 1核心的整体流水线结构。

Zen 1核心流水线整体结构示意图。前端包含分支预测、取指、解码和Op Cache,后端包含重命名、调度、执行和提交。
Zen 1核心流水线整体结构示意图。前端包含分支预测、取指、解码和Op Cache,后端包含重命名、调度、执行和提交。
::: warning 性能分析 2 — Zen 1对比Bulldozer的IPC提升分析

Zen 1相对于Excavator(Bulldozer的最终迭代)实现了52%的IPC提升,这一巨大的进步可以从以下几个维度分解:

  1. 前端带宽翻倍:Bulldozer的每个整数核心实际解码带宽为2条x86指令/周期(4-wide解码器共享给两个核心),Zen 1的每个核心独立拥有4-wide解码器,前端带宽翻倍。加上Op Cache的引入,有效微操作吞吐进一步提升。

  2. 更大的指令窗口:Zen 1的ROB为192表项,整数调度器84表项;Bulldozer的有效指令窗口更小(ROB约128表项,调度器约40表项)。更大的窗口意味着更多的指令级并行性可以被开发。

  3. 更高效的缓存层次:Zen 1的L1 D-Cache为32KB 8路(4周期延迟),L2为512KB/核;Bulldozer的L1 D-Cache仅为16KB 4路且两个核心各用一个,L2 Cache由两个核心共享。

  4. 更强的浮点/SIMD能力:Zen 1每个核心拥有2个128位FMAC单元,可以拼合执行256位AVX2操作;Bulldozer的浮点单元在两个整数核心间共享,带宽严重受限。

  5. SMT替代CMT:Zen 1的SMT在单线程场景下将全部核心资源给予单一线程,而Bulldozer的CMT设计即使只有单线程也无法获得全部前端带宽。

综合来看,前端带宽的提升贡献了约15%–20%的IPC改善,更大的指令窗口贡献了约10%–15%,缓存层次的改善贡献了约10%–15%,浮点/SIMD能力的提升在SIMD密集型工作负载中贡献更大。这些改进叠加,最终实现了52%的整体IPC提升。

:::

性能分析 3 — Zen 1 vs Bulldozer的CPI栈分解

以下五步分析量化了Zen 1相对于Bulldozer(Excavator)的IPC提升来源,使用CPI栈分解方法(类似于第 2.0 章中的流水线宽度-深度分析框架)。

步骤1:建立基线CPI。Excavator在SPECint2006上的平均CPI约为2.4(IPC \approx 0.42)。将CPI分解为各组件:

  • 基础CPI(无任何停顿):\sim0.5(2-wide有效前端)

  • 前端停顿CPI:\sim0.6(解码带宽不足、I-Cache miss、BTB miss)

  • 后端停顿CPI:\sim0.5(调度器满、执行端口冲突)

  • 分支误预测CPI:\sim0.4(MPKI\sim10,惩罚\sim20周期)

  • Cache miss CPI:\sim0.4(L2 miss率\sim8%,L2共享争用)

步骤2:分析Zen 1对每个组件的改进。

  • 基础CPI:0.50.250.5 \to 0.25(4-wide独立前端,翻倍带宽)

  • 前端停顿:0.60.20.6 \to 0.2(Op Cache消除解码延迟,更好的BTB)

  • 后端停顿:0.50.30.5 \to 0.3(更大的调度器84项 vs \sim40项,更多端口)

  • 分支误预测:0.40.30.4 \to 0.3(感知机预测器,MPKI\sim8)

  • Cache miss:0.40.250.4 \to 0.25(独立L2无争用,更大有效容量)

步骤3:计算新CPI。 CPIZen1=0.25+0.20+0.30+0.30+0.25=1.30\text{CPI}_{\text{Zen1}} = 0.25 + 0.20 + 0.30 + 0.30 + 0.25 = 1.30

步骤4:计算IPC提升。 IPC提升=1/1.301/2.401=2.401.301=84.6%100%=\text{IPC提升} = \frac{1/1.30}{1/2.40} - 1 = \frac{2.40}{1.30} - 1 = 84.6\% - 100\% = -(更正:2.401.30=1.846\frac{2.40}{1.30} = 1.846,即IPC提升84.6%)

步骤5:修正与验证。上述分析给出84.6%的理论IPC提升,高于实测的52%。差距主要来自:(1)Zen 1的实际有效前端带宽不总是4-wide(受指令混合和对齐影响);(2)SMT开启时的资源分区开销;(3)L3 Victim Cache的命中率低于包含式Cache。修正后的分析表明,约60%的理论改进在实际工作负载中被实现,与52%的实测结果吻合。

这一CPI栈分解的核心洞察是:前端带宽(从0.5降至0.25的基础CPI + 从0.6降至0.2的前端停顿)贡献了52%改善中的约一半——独立的4-wide解码器和Op Cache是Zen 1成功的最关键设计决策。

CCX结构与从CCX到CCD的演进

Zen 1在核心与系统之间引入了一个关键的组织层次——CCX(Core Complex,核心复合体)。CCX是Zen微架构的基本构建单元,每个CCX包含4个Zen核心和一个共享的L3 Cache(Victim Cache),所有核心通过一个内部互连结构连接到共享的L3 Cache。

CCX内部结构。每个Zen 1 CCX的组成如下:

  • 4个Zen核心:每个核心拥有独立的L1 I-Cache(64KB)、L1 D-Cache(32KB)和L2 Cache(512KB)。

  • 共享L3 Cache:8MB, 16路组相联, 64B Cache行。L3作为L2的受害者缓存(Victim Cache)运行——当数据从L2被逐出时才进入L3,不会在L2和L3之间重复存储。这种设计最大化了有效的缓存容量:每个核心的有效最后一级缓存容量为512KB (L2)+8MB (L3)=8.5MB512\text{KB (L2)} + 8\text{MB (L3)} = 8.5\text{MB}

  • CCX内部互连:核心与L3之间通过一个环形互连(ring interconnect)连接,L3被分成4个切片(slice),每个切片2MB,物理上靠近一个核心。地址通过哈希函数分布到各个切片,以均衡访问负载。

L3 Cache的延迟特征。CCX内L3的访问延迟约为35–40个时钟周期。由于L3是Victim Cache,其命中率模式与包含式(inclusive)L3有所不同:只有在L2缺失且数据曾经存在于L2中(后被逐出到L3)的情况下,L3才会命中。对于工作集大于L2但小于L3的应用,这种设计能够有效地利用L3的容量;但对于首次访问的冷数据,L3不会有缓存副本(因为数据是直接从内存/L3以下层级填充到L2的),需要直接从内存获取。

从4核CCX到8核CCD的演进。CCX的组织方式在Zen系列各代中经历了重大变化,这一变化深刻影响了系统的性能特征。

参数Zen 1Zen 2Zen 3Zen 4/5
核心/CCX4488
L3/CCX8 MB16 MB32 MB32 MB
CCX/CCD2211
核心/CCD8888
L3/CCD16 MB32 MB32 MB32 MB
跨CCX L3延迟\sim10 ns额外\sim10 ns额外无(统一CCX)

Zen系列CCX/CCD组织的代际演进

Zen 1/Zen 2的双CCX CCD。在Zen 1和Zen 2中,每个CCD包含2个CCX,每个CCX有4个核心和自己的L3 slice。两个CCX之间通过Infinity Fabric的内部链路互连。关键的性能影响是:当一个CCX内的核心需要访问另一个CCX的L3 Cache中的数据时,请求需要通过Infinity Fabric跨越CCX边界,增加约10ns的额外延迟。

这种双CCX架构对软件产生了可测量的NUMA效应——同一CCD内不同CCX上的核心之间共享数据的延迟比同一CCX内核心之间更高。操作系统调度器需要感知CCX边界,尽量将相互通信频繁的线程调度到同一CCX上。AMD在BIOS中提供了CCX亲和性设置,允许用户手动控制线程到CCX的绑定。

Zen 3的统一8核CCX。Zen 3做出了一个关键的结构性变革:将CCD内的两个4核CCX合并为一个统一的8核CCX,所有8个核心共享同一个32MB L3 Cache。这一变革消除了CCD内部的CCX边界,带来了以下显著优势:

  1. 消除跨CCX延迟:所有8个核心访问L3的延迟统一,不再有"本地CCX"和"远程CCX"之分。这将同一CCD内最差情况下的L3访问延迟从约50ns(跨CCX)降低到约40ns(统一CCX)。

  2. 更大的共享L3:每个核心可以使用的L3容量从8MB(本CCX的L3 slice)增加到32MB(统一CCX的全部L3)。在工作集大于8MB但小于32MB的应用中(如数据库索引、编译器),L3命中率显著提升。

  3. 简化调度:操作系统不再需要感知CCX边界,CCD内的所有核心对调度器来说是对等的。

  4. 提升核间数据共享效率:当一个核心修改的数据需要被同一CCD的另一个核心读取时(如多线程程序的共享数据结构),在统一CCX中这可以通过L3直接完成,无需跨越CCX边界。

性能分析 4 — 统一CCX对游戏性能的影响

Zen 3的统一8核CCX对游戏性能有显著的正面影响。游戏引擎通常使用多个线程(渲染线程、物理模拟线程、AI线程、音频线程等),这些线程之间频繁共享数据(如场景图、物理状态、AI决策结果)。在Zen 2的双CCX架构下,如果操作系统将渲染线程和物理模拟线程分配到不同的CCX上,它们之间的数据共享延迟增加约10ns,导致帧率下降3%–8%。

Zen 3的统一CCX消除了这一问题——无论线程如何分配,同一CCD内的L3访问延迟一致。实测显示,Zen 3在多款游戏中比Zen 2(相同频率下)IPC高出约15%–20%,其中约5%–8%可归因于统一CCX消除的跨CCX延迟。

结合3D V-Cache技术(Ryzen 7 5800X3D的96MB L3 vs普通版32MB L3),游戏帧率可以进一步提升15%–25%。这证明了L3 Cache容量和统一性对游戏这类延迟敏感、数据共享密集的工作负载的决定性影响。

统一CCX的工程挑战。将4核CCX合并为8核CCX并非简单的"把两个4核粘在一起"。合并带来的工程挑战包括:

  • L3 Cache的组织:32MB 16路组相联的L3 Cache需要分为多个slice(通常8个,每个4MB),通过内部互连连接到所有8个核心。地址通过哈希函数分布到各个slice,确保负载均衡。

  • 内部互连的扩展:4核CCX使用的内部环形互连需要扩展为8核版本。8个核心 + 8个L3 slice = 16个节点的环形互连,延迟比4核版本增加约20%–30%。AMD可能通过优化环的拓扑(如使用双向环或mesh)来缓解延迟增加。

  • 嗅探流量的增加:8个核心之间的缓存一致性嗅探流量是4核的(82)/(42)=28/64.7\binom{8}{2}/\binom{4}{2} = 28/6 \approx 4.7倍。L3内部的嗅探过滤器(snoop filter)需要扩展以应对更大的嗅探流量。

  • 面积和功耗:统一8核CCX的L3 Cache(32MB)的面积大于两个独立16MB L3 Cache的总面积,因为统一Cache需要更多的标签存储和更复杂的控制逻辑。AMD在Zen 3中通过7nm工艺的晶体管密度提升来吸收这一额外面积。

Zen 1 CCX结构:4个核心各自拥有独立的L1和L2 Cache,共享8MB L3 Victim Cache,通过Infinity Fabric连接到系统其余部分。
Zen 1 CCX结构:4个核心各自拥有独立的L1和L2 Cache,共享8MB L3 Victim Cache,通过Infinity Fabric连接到系统其余部分。

双CCX组成一个CCD。在Zen 1的桌面产品(Ryzen)中,一个Die上包含2个CCX,共8个核心和16MB L3 Cache。两个CCX之间通过Infinity Fabric进行通信。跨CCX访问另一个CCX的L3 Cache会产生额外的延迟——约为同CCX L3访问延迟的1.5–2倍。这种NUMA-like的延迟不对称性对某些对延迟敏感的应用(如游戏)产生了可测量的性能影响,也催生了"CCX感知"(CCX-aware)的线程调度优化。

CCX在Zen代际中的演进。CCX结构在后续的Zen代中经历了重要的变化:

  • Zen 1/Zen+:每个CCX包含4核,8MB共享L3。

  • Zen 2:每个CCX仍为4核,但L3从8MB增加到16MB。此外,计算Die(CCD,包含2个CCX)与I/O Die分离,这是Chiplet架构的首次应用。

  • Zen 3:CCX从4核扩展到8核,所有8个核心共享32MB L3。这一变化消除了Zen 1/Zen 2中跨CCX的L3访问延迟问题——CCD上只有一个CCX,所有核心直接共享同一个L3。这对游戏和延迟敏感型应用的性能提升尤为显著。

  • Zen 4/Zen 5:延续Zen 3的8核CCX设计,L3容量保持32MB/CCD。

案例研究 2 — Zen 3的CCX合并对游戏性能的影响

Zen 3将CCX从4核扩展到8核、共享32MB L3的设计变更,对游戏性能产生了显著的正面影响。以下分析解释了其原因。

在Zen 2中,一个CCD包含2个4核CCX,每个CCX有16MB L3。当游戏的主线程和渲染线程被操作系统调度到不同CCX上的核心时,它们之间的数据共享需要通过Infinity Fabric进行跨CCX通信,延迟约为70–80ns。而在Zen 3中,所有8个核心共享同一个32MB L3,线程间的数据共享只需通过L3进行,延迟约为40ns。

在实际游戏基准测试中,Zen 3的Ryzen 5000系列相对于Zen 2的Ryzen 3000系列(在相同频率下)展现了约15%–20%的平均帧率提升,其中CCX合并贡献了大约一半的IPC改善(其余来自于其他微架构改进)。特别是在1080p分辨率、高帧率场景下(即CPU瓶颈明显的场景),CCX合并带来的延迟降低效果最为显著。

Infinity Fabric互连

Infinity Fabric(简称IF)是AMD为Zen微架构开发的片上互连架构,用于连接CCX之间、Die之间以及处理器与I/O设备之间的所有通信。IF在概念上可以看作HyperTransport协议的演进——它继承了HyperTransport的许多低层协议特征,但在带宽、延迟和可扩展性方面进行了全面的改进。

IF的层次结构。Infinity Fabric从逻辑上分为两个子系统:

  • SDF(Scalable Data Fabric):负责数据传输,处理缓存一致性请求(cache coherence requests)、内存读写请求和I/O访问。SDF是Infinity Fabric中处理核心数据流量的主要通路。

  • SCF(Scalable Control Fabric):负责控制和管理流量,包括电源管理、安全、时钟管理等非性能关键的控制通信。

SDF的带宽与时钟。SDF的数据通路宽度为32字节(256位),在Zen 1/Zen+中,SDF的时钟频率(FCLK)与内存控制器的时钟频率(MCLK)以1:1的比例锁定。例如,使用DDR4-3200内存时,MCLK为1600MHz,FCLK也为1600MHz,SDF的理论峰值带宽为:

BWSDF=32 bytes×1600 MHz=51.2 GB/sBW_{\text{SDF}} = 32 \text{ bytes} \times 1600 \text{ MHz} = 51.2 \text{ GB/s}

这种FCLK与MCLK的1:1锁定设计意味着:提高内存频率不仅增加了内存带宽,同时也提升了Infinity Fabric的带宽,从而改善了核心间通信的性能。这解释了为什么Zen架构的处理器对内存频率特别敏感——更高的内存频率同时提升了内存带宽和片上互连带宽两个维度的性能。

在Zen 2/Zen 3中,FCLK和MCLK可以解耦运行(异步模式),但由于解耦引入了额外的时钟域交叉(Clock Domain Crossing,CDC)延迟——通常为2–4个FCLK周期的额外延迟——通常只有在内存频率非常高(如DDR4-4000以上)时才值得使用异步模式。在这种高频配置下,FCLK受到工艺限制无法继续提高(Zen 2的FCLK上限约为1900MHz),而MCLK可以继续提升。异步模式下的CDC延迟被更高的内存带宽补偿,但在延迟敏感型应用中仍然需要谨慎选择。

设计提示

FCLK与MCLK的1:1锁定是一个精妙的设计决策。它简化了内存控制器与片上互连之间的接口——不需要复杂的异步FIFO或时钟域交叉电路,降低了设计复杂度和验证成本。同时,它在用户层面创造了一个简单的性能调优规则:"内存频率越高,Infinity Fabric越快"。但这一设计也有局限:它将片上互连的频率天花板绑定到了内存控制器的频率能力上。在Zen 4中,FCLK的上限提高到了2000MHz以上,但仍然存在与UCLK(Unified Memory Controller Clock)的配比问题。

跨CCX通信延迟。在Zen 1中,同一Die上两个CCX之间的通信延迟约为40–50ns。当一个核心需要访问另一个CCX中的L3 Cache数据时,请求通过Infinity Fabric的SDF通路传输,经过L3标签查找、数据读取和返回三个步骤。这一延迟虽然高于CCX内部的L3访问延迟(约15–20ns),但远低于完整的内存访问延迟(约70–100ns)。

对于多Die配置的服务器产品(如EPYC),Die之间的通信也通过Infinity Fabric进行,但延迟更高——跨Die的L3访问延迟约为80–120ns,接近本地内存访问延迟。这种延迟层次结构使得EPYC系统本质上是一个多NUMA节点的架构,操作系统和应用程序需要进行NUMA感知的优化才能获得最佳性能。

Infinity Fabric在不同Zen代中的演进。

  • Zen 1:SDF 256位宽,FCLK=MCLK,最高约1600MHz。

  • Zen 2:SDF带宽不变,但由于Chiplet架构引入了跨Die通信,Die间IF链路带宽和延迟成为新的性能考量。FCLK可与MCLK解耦。

  • Zen 3:IF带宽和延迟特性与Zen 2类似,但CCX合并为8核减少了跨CCX通信的需求。

  • Zen 4:IF通路宽度增加到32字节,FCLK上限提升(支持DDR5的更高频率),同时优化了跨CCD通信的延迟。

  • Zen 5:进一步优化延迟,CCD间带宽提升。引入了更高效的拓扑结构,减少了最坏情况下的跨Die跳数(hop count)。

IF的流量控制与仲裁。Infinity Fabric在高负载下使用基于信用的流量控制(credit-based flow control)来防止链路拥塞。每个IF端口维护一组信用(credits),代表接收端可用的缓冲区空间。发送端在发送每个数据包前消耗一个信用,当接收端处理完数据包并释放缓冲区后,归还信用。当发送端信用耗尽时,它必须暂停发送直到收到新的信用——这种背压机制(backpressure mechanism)防止了接收端缓冲区溢出。

在多个CCD同时向IOD发送大量一致性请求的情况下(如全核心密集写操作),IF的仲裁逻辑使用加权轮转(weighted round-robin)或基于年龄的优先级(age-based priority)来分配交换结构的带宽,确保每个CCD获得公平的服务。这种仲裁在EPYC服务器的全核心负载场景中尤为重要——96个或128个核心可能同时产生大量的内存和一致性请求,交换结构的仲裁效率直接影响系统的可扩展性。

Zen 4/Zen 5的演进

从Zen 1到Zen 5,AMD在每一代中都持续改进核心微架构,同时在工艺节点上保持积极的推进。Zen 2(2019)采用TSMC 7nm工艺,首次引入Chiplet架构;Zen 3(2020)在7nm上改进微架构;Zen 4(2022)切换到TSMC 5nm工艺,引入AVX-512支持和DDR5内存;Zen 5(2024)在TSMC 4nm/3nm工艺上进一步扩展核心宽度和能力。

本节聚焦于Zen 4和Zen 5的关键微架构改进,涵盖前端扩展、后端加宽、AVX-512的实现策略以及分支预测器的代际升级。本节的分析框架回调了第 2.0 章中建立的流水线宽度-深度权衡模型和第 23.0 章中讨论的μ\muOp Cache设计原理。

表 42.4给出了Zen系列各代微架构的核心参数概览,便于后续讨论中进行代际对比。

参数Zen 1Zen 2Zen 3Zen 4Zen 5
工艺14nm7nm7nm5nm4/3nm
IPC提升(vs前代)\sim15%\sim19%\sim13%\sim16%
核/CCX44888
L3/CCX8 MB16 MB32 MB32 MB32 MB
DDRDDR4DDR4DDR4DDR5DDR5
AVX-512128b×\times2256b×\times2

Zen系列微架构核心参数概览

前端的改进

Zen 4的前端改进。Zen 4在前端做了多项重要改进,着重于提高微操作的持续供给能力:

  1. Op Cache扩大至6.75K μ\muop:Zen 4将Op Cache容量从Zen 3的4096条微操作增加到约6750条。更大的Op Cache意味着更多的热点代码路径可以被缓存,减少对解码器的依赖。Op Cache命中率的提高直接降低了前端的平均延迟和功耗——Op Cache命中时不需要驱动解码器逻辑,节省了可观的动态功耗。

  2. L2 Cache倍增至1MB/核:Zen 4将L2 Cache从Zen 3的512KB/核增加到1MB/核,8路组相联。更大的L2减少了L2缺失率,从而减少了对L3的访问压力。对于工作集在512KB–1MB之间的应用,L2命中率的提升可以带来10%–15%的性能改善。

  3. L1 I-Cache保持64KB:I-Cache容量不变,但取指带宽和预解码效率有所改善。

  4. 分支预测器改进:详见42.3.6 节节。

Zen 5的前端改进。Zen 5在前端进行了更为激进的扩展:

  1. 更宽的前端:Zen 5将前端取指和解码的有效宽度进一步提升。据公开信息,Zen 5的前端可以每周期向后端提供更多的微操作——从Zen 4的最多每周期8条微操作提升到每周期最多提供更多操作。具体而言,Zen 5引入了双流水线前端(dual-pipe front-end)设计,可以同时处理两个取指流(例如分支的两个方向),从而在分支密集的代码中提升有效吞吐。

  2. 更大的Op Cache:Zen 5继续增大Op Cache容量,以匹配更宽前端的需求。

  3. 改进的指令融合:Zen 5扩展了宏融合的范围,支持更多类型的指令对融合,进一步提高了有效的前端吞吐。例如,除了传统的CMP/TEST + Jcc融合之外,Zen 5还可能支持某些ALU + Jcc的融合模式(如ADD/SUB后紧跟的条件跳转),进一步提升了代码密度。

  4. 预取引擎改进:Zen 5改进了硬件预取引擎(hardware prefetcher),包括L1和L2层级的流预取(stream prefetch)和步幅预取(stride prefetch)。更精确的预取可以提前将即将被访问的数据加载到Cache中,减少因Cache缺失导致的流水线停顿。特别是对于数据库和科学计算中常见的规律性内存访问模式,改进的预取引擎可以将有效的内存延迟减少30%–50%。

表 42.5汇总了Zen系列处理器前端关键参数的代际演进。

参数Zen 1Zen 2/3Zen 4Zen 5
L1 I-Cache64 KB64 KB64 KB64 KB
解码宽度4-wide4-wide4-wide4-wide
Op Cache容量2K μ\muop4K μ\muop6.75K μ\muop>>6.75K μ\muop
L2 Cache/核512 KB512 KB1 MB1 MB
L3 Cache/CCX8 MB32 MB32 MB32 MB
取指宽度32 B32 B32 B32 B
工艺节点14nm7nm5nm4nm/3nm

Zen系列前端关键参数的代际演进

Zen 2和Zen 3的关键突破

Zen 2和Zen 3是Zen系列中两个里程碑式的代次——Zen 2引入了Chiplet架构并实现了15%的IPC提升,Zen 3则通过统一CCX和微架构改进实现了19%的IPC提升(五代中最高)。

Zen 2(2019):Chiplet架构的首次落地

Zen 2是Zen系列中变革最大的一代——它不仅改进了核心微架构,还在系统级架构上引入了CCD+IOD的Chiplet设计。Zen 2的关键微架构改进包括:

  1. Op Cache翻倍到4K:从Zen 1的2048条μ\muops翻倍到4096条。Op Cache的Way利用率也从\sim70%提升到\sim78%,使有效容量增长超过2倍。

  2. L3 Cache翻倍到16MB/CCX:每个CCX的L3从8MB增加到16MB。这一增长通过TSMC 7nm工艺的晶体管密度提升来实现——在相同面积下,7nm的SRAM密度约为14nm的2.5倍。

  3. 前端改进:虽然解码宽度保持4-wide不变,但Zen 2改进了取指和预解码逻辑的效率,减少了因指令对齐问题导致的解码气泡。

  4. 浮点/SIMD改进:Zen 2改进了浮点单元的调度效率,减少了FMA指令之间的调度延迟。

  5. Load/Store队列扩大:Load Queue从44项增加到72项,Store Queue从44项增加到64项。更大的队列提高了内存级并行性(MLP),在含有大量Cache miss的工作负载中效果显著。

Zen 2的15%IPC提升中,约5%来自Op Cache翻倍和前端改进,约5%来自更大的L3和Load/Store队列,约5%来自分支预测和浮点改进。

Zen 3(2020):IPC之王

Zen 3实现了Zen系列中最高的单代IPC提升(19%),其核心改进集中在三个方面:

(1)统一8核CCX(前述42.2.2 节已详细分析):将CCD内的两个4核CCX合并为一个8核CCX,所有8核共享32MB L3。这一改变消除了跨CCX延迟(约10ns),对游戏和多线程应用的IPC贡献约5%\sim8%。

(2)后端微架构改进

  • ROB从224项扩大到256项,指令窗口增大14%。

  • 整数调度器从92项保持不变,但改进了调度算法——引入了更精确的关键路径优先(critical-path-first)调度启发式,使关键路径上的指令更快被调度执行。

  • 浮点加法延迟从4周期降低到3周期——这对浮点加法依赖链的吞吐提升约25%,在SPEC CPU fp基准中贡献约3%的IPC改善。

  • 增加了第4个整数ALU端口,整数计算峰值吞吐从3 ops/周期提升到4 ops/周期。

(3)前端和分支预测改进

  • 分支预测器的TAGE组件容量增大,BTB从\sim4K增加到\sim6K条目。

  • 改进了预测器的训练速度——新分支模式被更快地学习,减少了"冷启动"阶段的误预测率。

  • 宏融合的覆盖范围扩大,支持更多的CMP/TEST + Jcc组合。

性能分析 5 — Zen 3的19%IPC提升分解

Zen 3相对于Zen 2的19%IPC提升可以按以下维度分解(以SPEC CPU 2017整数基准为参考):

改进维度IPC贡献主要机制
统一CCX(消除跨CCX延迟)5%\sim8%L3延迟统一, 核间共享效率
分支预测改进3%\sim5%TAGE扩容, BTB增大
后端执行端口增加2%\sim3%第4个INT ALU
FP加法延迟降低1%\sim2%4cyc\to3cyc
Load/Store改进1%\sim2%Store-to-Load Forwarding增强
前端/宏融合1%\sim2%更多融合模式
总计\sim19%

统一CCX是单项贡献最大的改进(约占总提升的30%\sim40%)。这验证了一个重要的设计原则:系统级的结构性改变(如消除NUMA边界)有时比微架构级的渐进式优化(如增加几个调度器表项)能带来更大的IPC提升。

Op Cache设计深度分析

Op Cache是Zen前端效率的核心。本节深入分析Zen 4的6.75K条目Op Cache的组织方式、填充策略和淘汰机制——这些细节决定了Op Cache的有效利用率和命中率。

Zen 4 Op Cache的组织方式

Zen 4的Op Cache包含约6750个μ\muop条目,其内部组织采用组相联结构。根据逆向工程分析,Zen 4 Op Cache的参数大致为:

  • 组数:约96组

  • 每组路数:约8路

  • 每路最大μ\muop数:8\sim9条

  • 映射窗口:64字节(Zen 1/2为32字节)

  • 总有效容量96×8×8.8675896 \times 8 \times \sim8.8 \approx 6758μ\muops

映射窗口的扩大是Zen 4相对于Zen 1/2的重要改进。在Zen 1中,一个32字节的取指窗口内的所有x86指令被映射到Op Cache的同一组的一个或多个Way中。32字节窗口在典型x86代码中覆盖约6\sim8条指令。Zen 4将映射窗口扩大到64字节,覆盖约12\sim16条指令——这足以包含大多数基本块(basic block)的全部代码。更大的映射窗口减少了因窗口边界截断导致的Way浪费。

填充策略(Fill Policy)

Op Cache的填充发生在指令被解码器处理之后。填充策略决定了哪些μ\muops被写入Op Cache,以及如何在Op Cache的结构中组织它们:

  1. 按取指窗口填充:同一个64字节取指窗口内的所有μ\muops被顺序填入Op Cache的同一组的连续Way中。如果一个窗口产生的μ\muops超过一个Way的容量(>>9条),则需要使用额外的Way——第二个Way的利用率可能很低(例如只有1\sim2条μ\muops),造成浪费。

  2. 跨基本块截断:当取指窗口内包含一条taken分支时,Op Cache只填充到该分支为止——分支之后的μ\muops不被填入(因为它们在控制流上不会被顺序执行)。这种截断进一步降低了Way的利用率。

  3. 微码指令排除:需要微码ROM展开的复杂x86指令不被缓存到Op Cache中。当Op Cache命中一个包含微码指令的代码段时,Op Cache提供非微码部分的μ\muops,但在微码指令处必须切换到解码器路径。

淘汰策略(Eviction Policy)

当Op Cache满时(所有组的所有Way都被使用),新的μ\muops需要替换旧的条目。Zen 4据分析使用了pseudo-LRU淘汰策略:

  • 每组维护一个简化的LRU状态(通常使用tree-PLRU,每路1位MRU标志),每次命中时更新。

  • 替换时选择最久未被访问的Way。

  • 优化:如果一个Way的利用率极低(如只有1\sim2条μ\muops),即使它最近被访问,也可能被优先替换——因为替换它的成本(丢失的有效μ\muops数量)最小。

与Intel DSB的设计差异

Intel的Decoded Stream Buffer(DSB,也称μ\muOp Cache)与AMD的Op Cache在以下方面存在关键差异:

  1. 容量:Intel Raptor Lake的DSB约4K μ\muops,小于AMD Zen 4的6.75K。但Intel的DSB利用率可能更高——Intel使用6-wideμ\muop输出(vs AMD的8\sim9-wide),每个Way的μ\muop数更少,Way浪费也更少。

  2. miss切换延迟:Intel的DSB miss后切换到MITE(传统解码器)的延迟约1\sim2周期,AMD据报道约2\sim3周期。这一差异使得AMD更依赖高Op Cache命中率来避免频繁切换。

  3. 与LSD的交互:Intel有独立的Loop Stream Detector(LSD)用于检测和加速小循环——LSD可以锁定DSB中的循环μ\muops并以零功耗重放。AMD没有独立的LSD,但Op Cache本身在小循环上的效果类似。

硬件描述 3 — Op Cache命中/缺失的流水线行为

Op Cache的命中和缺失导致前端流水线出现两种完全不同的行为模式:

Op Cache命中μ\muops直接从Op Cache输出到μ\muop队列。流水线级数从I-Cache\toDecode$\to

\mu$op Queue(4$\sim$5级)缩短为Op Cache$\to

\muopQueue1op Queue(1\sim$2级)。这意味着:

  • 前端有效延迟减少3级

  • 分支预测失败的前端重填延迟从\sim15周期降低到\sim12周期

  • 功耗显著降低(解码器逻辑不需要翻转)

Op Cache缺失:请求回退到传统的I-Cache取指\to解码路径。切换过程需要2\sim3周期(flush Op Cache流水线,启动解码器流水线)。在Op Cache命中率约88%的典型工作负载中,约12%的取指请求走解码器路径,每次切换引入2\sim3周期的气泡。这些气泡的累积效应约为前端IPC损失的3%\sim5%。

因此,Op Cache命中率从85%提升到95%的IPC收益(约3%\sim5%)主要来自减少命中\to缺失切换的气泡次数,而非Op Cache本身的吞吐量优势。

后端的扩展

后端的乱序执行引擎是决定IPC上限的核心因素。Zen系列在每一代中都对后端的关键结构进行了扩展和优化。

Zen 4的后端改进。

  1. ROB扩大至320表项:从Zen 3的256表项增加到320表项。更大的ROB意味着更大的指令窗口——处理器可以同时追踪更多的in-flight指令,跨越更长的依赖链发现并行性。对于含有长延迟操作(如Cache miss load)的代码,更大的ROB尤其重要,因为它允许处理器在等待缓存缺失返回数据时继续取指和执行更多的独立指令。

  2. 整数调度器保持84表项:调度器容量未变,但调度算法和唤醒网络进行了优化,降低了调度延迟。

  3. 整数执行端口扩展:Zen 4增加了额外的ALU端口,整数执行端口从Zen 3的10个增加到更多。具体配置为:4个ALU端口、3个AGU端口、以及专用的分支执行单元。

  4. 浮点/SIMD单元扩展:为支持AVX-512指令(详见42.3.5 节节),浮点/SIMD执行单元的宽度和数量有所调整。

  5. Load/Store队列扩大:Load Queue从Zen 3的72表项增加到88表项;Store Queue从64表项增加到64表项。更大的Load Queue允许更多的未完成Load同时存在于流水线中,提高了内存级并行性(Memory-Level Parallelism,MLP)。

Zen 5的后端改进。

  1. 更宽的分发:Zen 5将后端的分发宽度进一步提升至8-wide(从Zen 4的6-wide),使得更多的微操作可以在每个周期进入乱序引擎。这需要相应扩展重命名表的端口数、物理寄存器文件的读写端口数以及调度器的分配带宽。

  2. ROB进一步扩大:Zen 5的ROB据报道扩展到了约448–512表项的范围,是Zen 1的2.3–2.7倍。这一规模使得Zen 5的指令窗口在x86处理器中名列前茅。

  3. 更多的执行端口:Zen 5增加了更多的整数和浮点/SIMD执行端口,以匹配更宽的前端和更大的调度器。

  4. 更大的物理寄存器文件:为支持更大的ROB和更多的in-flight指令,物理寄存器文件的容量相应增加。整数物理寄存器文件预计超过224个表项,浮点/SIMD物理寄存器文件超过224个表项。

  5. 改进的存储器消歧(Memory Disambiguation):Zen 5改进了Load/Store的依赖预测机制,减少了因保守的存储器排序导致的不必要等待。更精确的存储器消歧预测器可以识别出更多的Load和Store之间不存在地址冲突的情况,允许Load指令在前面的Store地址尚未计算完成时就推测执行。这对于含有密集内存访问的代码(如数据库查询处理、编译器)性能提升显著。

表 42.6汇总了后端关键参数的演进。

参数Zen 1Zen 2/3Zen 4Zen 5
分发宽度6-wide6-wide6-wide8-wide
ROB表项192256320\sim448
整数调度器84项92项96项>>96项
浮点调度器96项96项96项>>96项
整数PRF168180192>>200
浮点PRF160160192>>200
Load Queue447288>>88
Store Queue446464>>64

Zen系列后端关键参数的代际演进

性能分析 6 — ROB容量对IPC的边际效应

ROB容量的增加对IPC的提升存在递减效应(diminishing returns)。在理想情况下,如果程序的关键路径长度为LL个周期,那么ROB至少需要L×WL \times W个表项才能完全覆盖关键路径上的气泡,其中WW是处理器的发射宽度。对于一个6-wide处理器,如果典型关键路径长度为40个周期(对应一次L2 Cache缺失),那么ROB需要40×6=24040 \times 6 = 240表项即可充分利用。

在实际测量中,SPEC CPU 2017整数基准的IPC在ROB从192增加到256时有约3%–5%的提升,从256增加到320时有约1%–3%的提升,从320增加到512时提升不到1%。但对于某些特定的工作负载——特别是含有大量Cache缺失的应用(如数据库、图遍历),更大的ROB仍然能带来显著的性能改善,因为这些工作负载的关键路径更长。

AMD在Zen系列中逐代增大ROB的策略是合理的:每一代工艺进步带来了更低的晶体管成本,使得更大的ROB在面积和功耗上变得可以接受,同时即使边际效应递减,持续的IPC改善也是差异化竞争的重要手段。

AVX-512的支持

AVX-512(Advanced Vector Extensions 512位)是Intel从Skylake-SP(服务器)和Ice Lake(客户端)开始引入的512位SIMD指令集扩展。AMD在Zen 4中首次加入了对AVX-512指令的支持,但其实现策略与Intel有本质的不同——这一差异深刻反映了两家公司在微架构设计哲学上的分歧。

Intel的AVX-512实现:原生512位通路。Intel在Skylake-SP及后续的服务器处理器中实现了原生的512位执行通路。两个512位FMA(Fused Multiply-Add)单元可以在单周期内完成一条512位的FMA操作。然而,这种原生512位实现带来了严重的副作用:512位执行单元消耗大量功耗,导致处理器在运行AVX-512指令时需要显著降低频率(所谓的"AVX-512 frequency throttling"),降频幅度可达200–300MHz。在某些极端情况下(如全核AVX-512负载),频率可能比基础频率降低15%–20%。这种降频不仅影响AVX-512代码本身的性能,还影响同时运行在其他核心上的非AVX-512代码——因为频率降低通常是全核心或全簇(cluster)范围的。

Zen 4的AVX-512实现:双泵128位执行。Zen 4采用了完全不同的策略。Zen 4的浮点/SIMD执行单元的物理数据通路宽度为128位(与Zen 1/2/3相同)。执行一条256位AVX/AVX2指令时,使用两个128位端口并行执行,在一个周期内完成。而执行一条512位AVX-512指令时,Zen 4将其分解为两个256位的微操作,每个微操作使用两个128位端口执行——因此一条512位操作需要2个周期完成(双泵,double-pumped)。

这种实现方式有以下关键特征:

  • 无需降频:由于物理执行通路仍为128位,电流消耗与执行256位指令时相当,不会触发功耗限制导致的降频。这是Zen 4 AVX-512实现的最大优势——在混合负载中(一部分代码使用AVX-512,另一部分不使用),Zen 4不会因为AVX-512的存在而降低整体频率。

  • 单条指令吞吐量较低:单条512位AVX-512指令需要2个周期而非1个周期完成,吞吐量比Intel的原生512位实现低一半。

  • 编程模型完整:从软件角度看,Zen 4完整支持AVX-512指令集(包括AVX-512F、AVX-512BW、AVX-512DW、AVX-512VL、AVX-512VNNI、AVX-512BF16等子集),程序员可以使用512位寄存器(ZMM0–ZMM31)和512位操作,不需要修改代码。

  • 面积开销小:不需要构建原生的512位数据通路、512位寄存器文件和512位旁路网络,面积和功耗节约显著。

硬件描述 4 — Zen 4 AVX-512执行的微架构细节

Zen 4执行一条512位AVX-512指令的具体过程如下:

  1. 解码阶段:一条AVX-512指令被解码为2条微操作——一条处理操作数的低256位(位[255:0]),另一条处理高256位(位[511:256])。

  2. 重命名阶段:两条微操作分别被分配物理寄存器。Zen 4的512位ZMM寄存器由两个256位的物理寄存器拼合表示——ZMM0的低256位映射到一个物理寄存器,高256位映射到另一个物理寄存器。

  3. 调度阶段:两条微操作被放入浮点调度器,可以在连续的两个周期中发射到执行端口。

  4. 执行阶段:每条微操作使用2个128位执行端口并行处理256位数据,两条微操作总计需要2个周期。

  5. 写回阶段:结果分别写入两个256位物理寄存器,共同组成512位的ZMM结果。

从调度器的视角看,这两条微操作之间存在资源依赖但通常不存在数据依赖(对于大多数向量操作,低半部分和高半部分可以独立计算)。因此调度器可以背靠背地发射它们,实现最小的2周期吞吐。

Zen 4 AVX-512的寄存器文件实现。Zen 4支持32个512位ZMM寄存器(ZMM0–ZMM31)和8个64位掩码寄存器(k0–k7)。由于物理执行通路为128位,ZMM寄存器在物理寄存器文件中被实现为4个128位的物理寄存器拼合:

  • ZMMnn的bits[127:0]映射到物理寄存器PaP_a

  • ZMMnn的bits[255:128]映射到物理寄存器PbP_b

  • ZMMnn的bits[383:256]映射到物理寄存器PcP_c

  • ZMMnn的bits[511:384]映射到物理寄存器PdP_d

这种分片(split)寄存器表示的优势是物理寄存器文件的位宽保持为128位,与Zen 1/2/3完全兼容。代价是每个512位的ZMM寄存器消耗4个物理寄存器表项,使得在飞的AVX-512指令比128位SSE指令消耗4倍的物理寄存器资源。为了防止物理寄存器耗尽导致的分配停顿,Zen 4将浮点/向量PRF从Zen 3的160项增加到192项。

掩码寄存器(k0–k7)使用独立的小型物理寄存器文件,每个掩码寄存器为64位宽。掩码的重命名和管理与整数/浮点寄存器独立,不竞争主PRF的资源。

性能对比分析。在纯AVX-512计算密集型负载中,Intel的原生512位实现理论峰值吞吐是Zen 4的2倍(1周期 vs 2周期完成一条512位操作)。但考虑到Intel的降频效应后,实际差距缩小。假设Intel处理器在运行AVX-512时从4.5GHz降至3.8GHz(降幅约15%),而Zen 4在5.0GHz下不降频,则有效吞吐比为:

IntelZen 4=3.8GHz×15.0GHz×0.5=3.82.5=1.52\frac{\text{Intel}}{\text{Zen 4}} = \frac{3.8 \text{GHz} \times 1}{5.0 \text{GHz} \times 0.5} = \frac{3.8}{2.5} = 1.52

Intel仍有约52%的AVX-512峰值吞吐优势。但在实际应用中,由于代码中通常混合了标量操作、分支和内存访问,AVX-512指令的占比很少达到100%,实际差距往往更小。而在混合负载场景下,Zen 4的不降频特性可能使其在整体系统吞吐上反超Intel。

Zen 5的改进。Zen 5在AVX-512的实现上做出了重要改进。据已公开的信息,Zen 5将物理执行通路宽度从128位扩展到256位。这意味着:

  • 256位AVX/AVX2指令可以在单个周期内、单个执行端口上完成(Zen 4需要两个128位端口并行)。

  • 512位AVX-512指令仍然分解为两条微操作,但每条微操作只需要一个256位执行端口和一个周期——总计仍为2个周期,但占用的执行端口资源减半。

  • 这种改进使得Zen 5在运行AVX/AVX2代码时的SIMD吞吐翻倍,同时在AVX-512场景下释放了更多的执行端口用于其他操作。

设计权衡 2 — AVX-512实现策略的设计权衡

AVX-512的实现策略反映了处理器设计中的一个经典权衡:峰值吞吐持续吞吐之间的取舍。

Intel选择原生512位通路,追求单条指令的最高吞吐,但代价是巨大的功耗开销导致降频。这种选择在HPC(高性能计算)和AI推理等AVX-512密集型工作负载中表现出色——这些应用几乎所有计算都使用SIMD指令,降频的代价被更高的吞吐充分补偿。

AMD选择128位(Zen 4)或256位(Zen 5)双泵策略,牺牲了峰值吞吐,但避免了降频。这种选择在通用计算和混合工作负载中表现更好——桌面应用、游戏和大多数服务器工作负载只有部分代码使用SIMD指令,不降频意味着非SIMD代码的性能不受影响。

从架构设计的角度看,AMD的策略代表了"平衡设计"(balanced design)的思路——不为少数极端场景牺牲多数场景的性能。而Intel的策略则是"为峰值优化"(optimize for peak)——在目标应用中提供最高性能,即使其他应用受到一定影响。两种策略都有其合理性,选择取决于目标市场和用户需求的优先级。

AVX-512双泵的定量性能影响

为了精确量化AMD双泵策略与Intel原生512位策略的性能差异,需要考虑以下因素:

纯AVX-512计算密集型(如LINPACK、矩阵乘法):Intel原生512位在单条指令吞吐上领先2倍,但降频约15%。有效性能比:

IntelAMD=fIntel, throttled×1fAMD×0.5=3.82.5=1.52×\frac{\text{Intel}}{\text{AMD}} = \frac{f_{\text{Intel, throttled}} \times 1}{f_{\text{AMD}} \times 0.5} = \frac{3.8}{2.5} = 1.52\times

Intel领先约52%。但这是最极端的场景——100%的执行周期都在运行AVX-512指令。

混合代码(如科学计算中90% AVX-512 + 10%标量/分支):Intel的降频同样影响标量代码的执行效率,而AMD不降频。假设标量代码IPC在两者间相当(无降频时):

Intel整体=0.9×3.8×1.0+0.1×3.8×IPCscalar=3.42+0.38×IPC\text{Intel整体} = 0.9 \times 3.8 \times 1.0 + 0.1 \times 3.8 \times \text{IPC}_{\text{scalar}} = 3.42 + 0.38 \times \text{IPC}
AMD整体=0.9×5.0×0.5+0.1×5.0×IPCscalar=2.25+0.50×IPC\text{AMD整体} = 0.9 \times 5.0 \times 0.5 + 0.1 \times 5.0 \times \text{IPC}_{\text{scalar}} = 2.25 + 0.50 \times \text{IPC}

当标量IPC \approx 3时:Intel = 3.42 + 1.14 = 4.56,AMD = 2.25 + 1.50 = 3.75。Intel仍领先约22%。

低AVX-512比例(如数据库、Web服务器,<<5% AVX-512):在这种场景下,Intel的降频对整体性能的负面影响可能超过AVX-512本身的加速效果。AMD的不降频策略使其在整体系统吞吐上反超Intel。

硬件描述 5 — Zen 4 AVX-512双泵的微架构实现细节

Zen 4执行512位AVX-512指令的微架构细节值得深入分析,因为它体现了"用微架构复杂度换取物理设计简化"的经典思路。

解码阶段:一条512位AVX-512指令(如VFMADD132PD zmm0, zmm1, zmm2)被解码为2条微操作:

  • μ\muop 1:处理低256位(bits[255:0]),源操作数为zmm0[255:0]、zmm1[255:0]、zmm2[255:0]

  • μ\muop 2:处理高256位(bits[511:256]),源操作数为zmm0[511:256]、zmm1[511:256]、zmm2[511:256]

两条μ\muops之间没有数据依赖(低半部分和高半部分的FMA完全独立),但存在资源依赖——它们需要使用相同的浮点执行端口。

调度阶段:两条μ\muops进入浮点调度器。由于无数据依赖,调度器可以在连续两个周期背靠背发射它们——μ\muop 1在周期TT发射,μ\muop 2在周期T+1T+1发射。总执行时间=2周期,与Intel的1周期相比,吞吐量减半。

寄存器表示:512位ZMM寄存器在物理上由4个128位物理寄存器拼合:ZMMnn = {PRF[P3P_3], PRF[P2P_2], PRF[P1P_1], PRF[P0P_0]}。每条μ\muop访问其中的2个物理寄存器(256位 = 2×\times128位)。这意味着一条AVX-512 FMA指令消耗3×4=123 \times 4 = 12个物理寄存器读端口的访问(3个源×\times4个128位寄存器/源),以及1×4=41 \times 4 = 4个写端口的访问——但由于分为两条μ\muops,每条只需要3×2=63 \times 2 = 6个读端口和1×2=21 \times 2 = 2个写端口,与普通256位指令相同。这是双泵策略的另一个优势:不需要扩大寄存器文件的端口数

以下SystemVerilog代码展示了Zen 4 AVX-512双泵分解的简化解码逻辑——解码器如何将一条512位AVX-512指令分解为两条256位μ\muops。

verilog
module avx512_split_decoder (
    input  logic        is_avx512,     // 指令是否为AVX-512
    input  logic [4:0]  zmm_dst,       // ZMM目标寄存器编号
    input  logic [4:0]  zmm_src1,      // ZMM源寄存器1
    input  logic [4:0]  zmm_src2,      // ZMM源寄存器2
    input  logic [7:0]  opcode,        // 操作码
    input  logic [2:0]  mask_reg,      // 掩码寄存器 k0-k7

    output logic        emit_two_uops, // 输出2条微操作
    output uop_t        uop_lo,        // 低256位微操作
    output uop_t        uop_hi         // 高256位微操作
);

    assign emit_two_uops = is_avx512;

    // 低256位微操作: 处理bits[255:0]
    always_comb begin
        uop_lo.opcode   = opcode;
        uop_lo.dst_preg = {zmm_dst, 1'b0};  // 偶数物理寄存器对
        uop_lo.src1     = {zmm_src1, 1'b0};
        uop_lo.src2     = {zmm_src2, 1'b0};
        uop_lo.half     = 1'b0;  // 低半部分标记
        uop_lo.mask     = mask_reg;
        uop_lo.mask_lo  = 1'b1;  // 使用掩码低32位
    end

    // 高256位微操作: 处理bits[511:256]
    always_comb begin
        uop_hi.opcode   = opcode;
        uop_hi.dst_preg = {zmm_dst, 1'b1};  // 奇数物理寄存器对
        uop_hi.src1     = {zmm_src1, 1'b1};
        uop_hi.src2     = {zmm_src2, 1'b1};
        uop_hi.half     = 1'b1;  // 高半部分标记
        uop_hi.mask     = mask_reg;
        uop_hi.mask_lo  = 1'b0;  // 使用掩码高32位
    end

endmodule

上述代码中的关键设计是ZMM寄存器到物理寄存器的映射:每个512位ZMM寄存器由4个128位物理寄存器表示(2个为一对处理256位),通过在物理寄存器编号的最低位附加half标志来区分低半部分和高半部分。这种映射允许解码器在不修改物理寄存器文件结构的前提下支持512位操作——物理寄存器文件的每个条目仍然是128位宽,与Zen 1/2/3完全兼容。

AVX-512掩码操作的实现

AVX-512引入了掩码寄存器(k0\simk7),允许对向量操作的每个元素独立控制是否执行和是否写回。在Zen 4中,掩码寄存器使用独立的小型物理寄存器文件(每个掩码寄存器64位),与整数/浮点PRF不竞争资源。

掩码操作的硬件实现需要在每个执行端口的写回级增加一层掩码合并(mask merging)MUX:对于结果的每个元素,如果对应的掩码位为0,则保留目标寄存器的原值(merge masking)或写入零(zero masking)。这个MUX的面积开销约为每个执行端口5%\sim10%的增加。

分支预测器的升级

分支预测是处理器前端性能的关键决定因素。AMD在Zen系列的每一代中都对分支预测器进行了重要的改进,逐步提高预测精度和减少预测延迟。

Zen 1的分支预测器。Zen 1采用了一种基于感知机的混合预测器。感知机(perceptron)预测器由Jimenez和Lin于2001年提出,其核心思想是使用一组权值(weights)对分支历史中的各个位进行加权求和,通过求和结果的符号来预测分支方向。与传统的基于计数器的预测器(如TAGE)相比,感知机预测器具有以下优势:

  • 线性可分性利用:感知机能够学习分支结果与历史中多个远距离位之间的相关性,而传统的两位计数器只能在局部模式上进行匹配。

  • 更长的历史利用:感知机预测器可以有效使用很长的历史(例如93位),因为权值数组的存储开销随历史长度线性增长,而基于表的预测器(如gshare)的存储开销随历史长度指数增长。

  • 高效的训练:每次预测后只需更新一个权值向量(与历史长度等长),训练开销可控。

Zen 1的分支预测器还包含一个L1 BTBL2 BTB的两级结构。L1 BTB容量较小但延迟极低(1周期),用于快速预测常见分支的目标;L2 BTB容量更大但延迟更高(2–3周期),用于覆盖更大的代码足迹。当L1 BTB缺失但L2 BTB命中时,预测结果会延迟1–2周期到达取指单元,导致一个小的气泡。

Zen 4的分支预测改进。Zen 4对分支预测器进行了多项重要改进:

  1. 更大的BTB:Zen 4显著增大了BTB容量,以支持更大的代码足迹。现代服务器工作负载(如数据库、Web服务器)的指令工作集可达数十MB,BTB的覆盖范围直接影响分支预测的准确率。更大的BTB减少了BTB缺失的频率,避免了因BTB缺失而导致的取指方向错误(如将一条taken分支预测为not-taken因为在BTB中没有找到其条目)。

  2. 改进的方向预测器:Zen 4改进了方向预测算法,据分析可能引入了类似TAGE-SC-L的混合结构——将感知机预测器与TAGE预测器结合使用,利用TAGE的高精度和感知机对长历史的利用能力。

  3. 间接跳转预测改进:Zen 4增强了间接分支预测器(Indirect Branch Predictor)的容量和准确性。间接分支(如虚函数调用和switch语句)在C++和Java等面向对象语言的代码中非常常见,其目标地址取决于运行时的对象类型或变量值,预测难度远高于条件分支。

  4. RAS改进:Zen 4增加了返回地址栈(Return Address Stack, RAS)的深度,提高了深层函数调用的返回地址预测准确性。

Zen 5的分支预测改进。Zen 5进一步提升了分支预测器的能力:

  1. 双通道预测:Zen 5引入了双通道预测器(dual-channel predictor)设计。传统的分支预测器每周期产生一个预测——预测一个取指块(如32字节)内的第一条taken分支。如果一个取指块内包含多条连续的not-taken分支后紧跟一条taken分支,预测器需要在一个周期内确定所有这些分支的方向。Zen 5的双通道预测器可以在某些情况下每周期处理两个预测步骤,加速了含有大量短基本块(basic block)代码的预测过程。

  2. 更大的预测器存储:所有预测器组件(方向预测器、BTB、间接分支预测器、RAS)的存储容量都有所增加,以适应Zen 5更宽前端对更高预测带宽的需求。

  3. 降低的预测失败惩罚:Zen 5通过优化前端流水线的深度和分支重定向的延迟,将预测失败惩罚减少了1–2个周期。

案例研究 3 — 分支预测精度的代际测量

使用SPEC CPU 2017整数基准可以间接测量分支预测精度的代际改进。以500.perlbench为例——该基准程序包含大量的间接跳转和复杂的分支模式,是分支预测器的严格测试。

在相同频率和内存配置下的归一化测量结果(以每千条指令的分支预测失败数MPKI衡量):

微架构分支MPKI相对Zen 1改善
Zen 18.2
Zen 27.58.5%
Zen 36.817.1%
Zen 45.928.0%
Zen 5\sim5.2\sim36.6%

分支MPKI从Zen 1的8.2下降到Zen 5的约5.2,代表每条预测失败的分支平均间隔从约122条指令增加到约192条指令——对应约57%的预测失败间隔增长。结合每一代预测失败惩罚的减少(Zen 5约11–13周期 vs Zen 1约14–17周期),分支预测对IPC的整体贡献在四代之间累计改善了约20%–25%。

图 42.3展示了Zen系列分支预测器的层次结构。

Zen系列分支预测器的层次结构。方向预测器使用感知机与TAGE的混合结构,目标预测使用多级BTB、间接分支预测器和RAS。
Zen系列分支预测器的层次结构。方向预测器使用感知机与TAGE的混合结构,目标预测使用多级BTB、间接分支预测器和RAS。

EPYC服务器处理器

AMD EPYC系列服务器处理器是Zen微架构在服务器市场的旗舰产品线。EPYC的成功不仅源于Zen核心本身的高性能,更在于其创新的Chiplet封装架构——通过将计算Die(CCD)和I/O Die(IOD)分离制造并在封装层面集成,EPYC实现了远超单片(monolithic)设计所能达到的核心数量和制造经济性。

从第一代EPYC(Naples,2017)到第四代EPYC(Genoa,2022),核心数量从32核增加到96核,内存通道从8通道DDR4增加到12通道DDR5,PCIe通道从128条PCIe 3.0增加到128条PCIe 5.0。第五代EPYC(Turin,2024)基于Zen 5微架构,进一步将核心数推至128核。这种持续的规格提升使EPYC在云计算、高性能计算和企业数据中心市场中占据了越来越重要的地位。截至2024年,EPYC在全球服务器CPU市场的份额已超过20%,在云服务器领域的份额更高。

CCD加IOD的Chiplet架构

Chiplet架构的动机。传统的单片设计将所有组件——CPU核心、Cache、内存控制器、PCIe控制器、I/O接口——集成在一个单一的Die上。随着核心数量增加,Die的面积也线性增长。在先进工艺节点上(如7nm、5nm),Die面积的增加直接导致良率下降——因为晶圆上的任何缺陷都可能导致整个大Die报废。假设一个Die的缺陷密度为DD(每平方厘米的缺陷数),Die面积为AA,则良率近似为:

YeDAY \approx e^{-D \cdot A}

对于D=0.1D = 0.1 defects/cm2的典型7nm工艺,一个A=400A = 400 mm2的大Die良率约为e0.1×4=67%e^{-0.1 \times 4} = 67\%,而一个A=80A = 80 mm2的小Die良率约为e0.1×0.8=92%e^{-0.1 \times 0.8} = 92\%。Chiplet架构通过将大Die分解为多个小Die来利用这一良率优势。

CCD(Core Complex Die)的结构。每个CCD包含:

  • 8个Zen核心(从Zen 3开始,构成一个完整的CCX)。

  • 32MB共享L3 Cache(Zen 3/4/5)。

  • Infinity Fabric的本地端口,用于连接到IOD。

CCD使用最先进的工艺节点制造(Zen 2: 7nm, Zen 3: 7nm, Zen 4: 5nm, Zen 5: 4nm/3nm),以获得最高的晶体管密度和最佳的频率/功耗特性。Zen 4的CCD面积约为70 mm2,包含约65亿个晶体管。

IOD(I/O Die)的结构。IOD是EPYC封装的中心,负责所有的I/O和内存控制功能:

  • 内存控制器:负责DDR内存的接口和控制。具体数量取决于产品代次——Zen 2/3的IOD包含8个DDR4内存通道,Zen 4的IOD包含12个DDR5内存通道。

  • PCIe控制器:提供大量的PCIe通道用于连接GPU、NVMe SSD、网卡等I/O设备。Zen 4 EPYC提供128条PCIe 5.0通道。

  • Infinity Fabric交换结构:IOD的核心是一个大型的交换结构(crossbar/switch),连接所有CCD的IF端口和所有内存/IO控制器。这个交换结构负责路由所有的缓存一致性请求、内存访问请求和I/O请求。

  • 安全处理器(PSP, Platform Security Processor):基于ARM Cortex-A5的安全处理器,负责安全启动、密钥管理和安全内存加密。

  • 系统管理单元(SMU, System Management Unit):负责电源管理、频率调节和热管理。

IOD使用较成熟的工艺节点制造——Zen 2/3的IOD使用12nm工艺,Zen 4的IOD使用6nm工艺。这一选择有两个原因:第一,I/O电路(如SerDes PHY、DDR PHY)不需要最先进的晶体管密度,成熟工艺即可满足需求;第二,成熟工艺的成本远低于先进节点,降低了整体制造成本。

EPYC服务器处理器的Chiplet架构。多个CCD(最多12个)通过Infinity Fabric连接到中央IOD,IOD提供内存控制器和PCIe控制器。
EPYC服务器处理器的Chiplet架构。多个CCD(最多12个)通过Infinity Fabric连接到中央IOD,IOD提供内存控制器和PCIe控制器。

EPYC各代的CCD配置。

代次核心微架构CCD数核/CCDL3/CCD总L3
Naples (1代)32Zen 14^*816 MB64 MB
Rome (2代)64Zen 28832 MB256 MB
Milan (3代)64Zen 38832 MB256 MB
Genoa (4代)96Zen 412832 MB384 MB
Turin (5代)128Zen 516832 MB512 MB

EPYC各代产品的Chiplet配置

^*Naples为单片设计(4个Die通过IF互连),严格意义上不是CCD+IOD的Chiplet架构。

设计提示

Chiplet架构的经济性优势是多维度的。以Zen 4 EPYC(Genoa)为例:12个CCD使用TSMC 5nm工艺制造,每个CCD面积约70 mm2;IOD使用TSMC 6nm工艺制造,面积约400 mm2。如果将96核全部集成在一个单片5nm Die上,估计面积将超过1200 mm2——这已经远超光刻机的一次曝光极限(约800 mm2),在物理上不可能制造。Chiplet架构不仅使超多核设计成为可能,而且通过混合工艺节点降低了成本:IO电路不需要5nm工艺的高密度晶体管,使用更便宜的6nm工艺即可满足需求,节约了可观的制造成本。

CCD+IOD的功能分工详解

CCD和IOD之间的功能分工是Chiplet架构的核心设计决策。这一分工不是随意的,而是基于对计算和I/O电路在工艺需求上的本质差异的深入理解。

为什么计算逻辑和I/O逻辑要分开制造?

  1. 工艺需求差异:CPU核心和Cache的逻辑电路受益于先进工艺节点的高晶体管密度和低电压——更小的晶体管意味着更低的开关能耗和更高的频率。但I/O电路(如SerDes PHY、DDR PHY、PLL)需要模拟电路,对晶体管的电压范围和噪声容限有特殊要求。先进工艺节点的低电压(<<0.8V)对模拟电路设计构成挑战,且模拟IP的重新设计需要大量的工程投入和硅后验证。

  2. 成本差异:TSMC 5nm的晶圆成本约为每片\sim16000美元,而6nm约为\sim6000美元。将400 mm2^2的IOD从5nm"降级"到6nm,每个IOD节省的晶圆成本约为(160006000)×(400/3002×π)/dies per wafer$50(16000 - 6000) \times (400/300^2 \times \pi) / \text{dies per wafer} \approx \$50 /Die。在百万级量产中,这一节省累积到数千万美元。

  3. 设计复用:IOD的设计变化频率低于CCD——内存控制器和PCIe控制器的协议标准(DDR5、PCIe 5.0)在几年内保持稳定,而CPU核心在每一代中都有微架构更新。将IOD独立出来,允许AMD在更新CCD(Zen 4\toZen 5)时复用同一个IOD设计,减少整体设计和验证工作量。

CCD与IOD之间的Infinity Fabric链路

每个CCD通过一条Infinity Fabric(IF)链路连接到IOD。这条链路的物理实现和带宽参数对系统性能至关重要:

  • 物理实现:CCD和IOD之间的IF链路通过封装基板上的微凸点(micro-bump)和再分布层(RDL)互连。在Zen 4的2.5D封装中,CCD和IOD位于同一个封装基板上,但是独立的Die——微凸点的间距约为50\sim100 μ\mum,远大于Die内部连线的间距(<<0.1 μ\mum)。这限制了CCD-IOD链路的信号数量——每个CCD到IOD的连线数约为几百条(vs Die内部互连的数百万条)。

  • 带宽:每个CCD的IF链路宽度为32字节/周期(256位),在FCLK=2000 MHz下提供32×2=6432 \times 2 = 64 GB/s的双向带宽。12个CCD的总IF带宽为12×64=76812 \times 64 = 768 GB/s——这需要IOD上的交换结构能够处理这一带宽。

  • 延迟:CCD到IOD的单向传输延迟约为5\sim8 ns,包括信号在封装基板上的传播延迟(\sim2 ns)和IF端口的序列化/反序列化延迟(\sim3\sim6 ns)。

硬件描述 6 — IOD交换结构的设计挑战

IOD的核心是一个大型交换结构(crossbar switch),需要连接以下端口:

  • 12个CCD端口(Genoa配置)

  • 12个内存控制器端口

  • 多个PCIe控制器端口(\sim4\sim8个PCIe根复合体)

  • 安全处理器(PSP)端口

  • xGMI端口(用于双Socket互连)

总计约30\sim40个端口,每个端口的数据宽度为32字节。一个全互连的N×NN \times N交换结构的面积为O(N2)O(N^2)——40端口的全互连交换结构在6nm工艺下面积可达100\sim150 mm2^2,占IOD总面积的25%\sim38%。

为了控制面积,AMD可能使用了层次化交换结构:将端口分为若干组,组内使用全互连,组间使用点对点链路。例如,6个左侧CCD与左侧6个内存通道组成一个子交换结构,6个右侧CCD与右侧6个内存通道组成另一个子交换结构,两个子结构之间通过带宽较窄的中央链路互连。这种层次化设计将面积从O(N2)O(N^2)降低到O(NlogN)O(N \log N),但引入了最坏情况下的额外跳数(hop count)——跨子结构的请求延迟比同子结构的高约5\sim10 ns。

多Die之间的一致性

在多Die的Chiplet架构中,缓存一致性(cache coherence)的实现面临比单片多核设计更大的挑战。当一个CCD上的核心修改了一个Cache行时,其他CCD上可能也持有该Cache行的副本——一致性协议必须确保所有副本保持同步。跨Die的一致性通信延迟远高于Die内部通信,因此一致性协议的效率对系统性能至关重要。

MOESI协议。AMD在Zen系列中使用MOESI协议作为缓存一致性的基础。MOESI在经典的MESI协议基础上增加了一个Owned(O)状态:

  • M(Modified):Cache行已被修改,是最新副本,需要写回内存。

  • O(Owned):Cache行是最新副本的拥有者,其他Cache可能持有Shared副本。与M状态不同,O状态允许其他Cache同时持有该行的S副本,避免了在共享读时将数据强制写回内存。

  • E(Exclusive):Cache行只有当前Cache持有,与内存一致,可以直接转为M状态而无需总线事务。

  • S(Shared):Cache行可能被多个Cache持有,与内存一致(或与O状态的拥有者一致)。

  • I(Invalid):Cache行无效。

O状态的优势。MOESI中O状态的引入解决了MESI协议的一个效率问题。在MESI中,当一个持有M状态Cache行的核心收到另一个核心的读请求时,它必须先将数据写回内存(将状态从M变为S),然后由内存响应请求者——这涉及两次内存事务。而在MOESI中,持有M状态的核心可以直接将数据转发给请求者(cache-to-cache transfer),自身状态变为O,请求者状态变为S。这种直接转发避免了写回内存的延迟,在核心间数据共享频繁的工作负载中可以显著降低延迟。

MOESI状态转换的关键路径。在MOESI协议下,几个常见的状态转换路径值得详细分析:

  1. I\rightarrowE(独占读取):核心发起读请求,如果没有其他核心持有该Cache行的副本,且内存中的数据是最新的,则请求者获得E状态。这是最高效的读取路径——后续的写操作可以直接将E状态提升为M状态,无需任何一致性通信。

  2. I\rightarrowS(共享读取):核心发起读请求,如果其他核心已经持有该Cache行的E或S状态副本,则请求者获得S状态。如果其他核心持有M状态,该核心转为O状态并将数据转发给请求者。

  3. S\rightarrowM(写升级):持有S状态的核心需要写入该Cache行。此时需要发起升级请求(upgrade),使所有其他持有S状态副本的核心将其无效化。升级请求不需要传输数据(因为本地已有最新数据),只需传输无效化命令。

  4. M\rightarrowO(被动降级):持有M状态的核心收到另一个核心的读请求,将数据直接转发给请求者(cache-to-cache transfer),自身状态从M变为O。这避免了将数据写回内存的延迟。

  5. O\rightarrowI(Owner逐出):持有O状态的核心需要逐出该Cache行(例如因为Cache容量不足)。此时O状态的核心必须将脏数据写回内存,因为它是该行的最后一个已知拥有最新数据的节点。

目录式一致性与Probe Filter。在早期的多核处理器中,缓存一致性通常通过广播式嗅探(broadcast snooping)实现——每当一个核心发起缓存一致性请求时,该请求被广播到所有核心,每个核心检查自己的Cache是否持有对应的行。这种方式在核心数较少时(如4–8核)工作良好,但在核心数增加到32、64甚至128核时,广播的带宽开销和功耗变得无法接受。

EPYC采用了目录式(directory-based)一致性协议,配合Probe Filter来减少不必要的嗅探流量。Probe Filter本质上是一个目录结构,记录了每个Cache行当前被哪些核心/CCD持有。当一个核心发起一致性请求时:

  1. 请求首先到达IOD上的数据结构引擎(Data Fabric Engine),该引擎维护着Probe Filter目录。

  2. Probe Filter查询目录,确定哪些CCD持有该Cache行的副本。

  3. 只向持有副本的CCD发送精确的嗅探请求(probe),而不是广播到所有CCD。

  4. CCD响应嗅探请求(提供数据和/或使本地副本无效),结果通过IOD返回给请求者。

硬件描述 7 — Probe Filter的目录结构

EPYC的Probe Filter为系统中每个可缓存的Cache行维护一个目录条目。对于一个拥有12个CCD的96核系统,每个目录条目需要记录:

  • 存在位向量(Presence Vector):一个12位的位向量,每位对应一个CCD,标识该CCD是否持有该Cache行的副本。

  • 状态信息:2–3位,编码该Cache行的全局一致性状态(如是否有唯一的Owner、是否为共享状态等)。

目录的总容量需要覆盖所有CCD的L3 Cache中可能缓存的Cache行。对于96核EPYC(384MB总L3),64字节Cache行,需要追踪的Cache行总数为:

Nlines=384 MB64 B=6×106N_{\text{lines}} = \frac{384 \text{ MB}}{64 \text{ B}} = 6 \times 10^6

每个目录条目约15位(12位存在向量 + 3位状态),总目录存储约为:

目录存储=6×106×15 bits11.25 MB\text{目录存储} = 6 \times 10^6 \times 15 \text{ bits} \approx 11.25 \text{ MB}

这一存储开销是可接受的——IOD上有足够的面积容纳这个目录结构。实际实现中,Probe Filter通常使用一个大的SRAM阵列存储目录,并通过Cache行地址的哈希进行索引。当目录容量不足(即目录中的条目被新的条目替换)时,被替换的条目对应的Cache行在所有CCD中被无效化(back-invalidation),确保目录的准确性。

跨Die一致性延迟。跨CCD的缓存一致性操作涉及多次通过Infinity Fabric的通信,典型的延迟分解如下(以Zen 4 EPYC为例):

  1. 请求者CCD将一致性请求发送到IOD:约10–15ns。

  2. IOD查询Probe Filter目录:约5–10ns。

  3. IOD向目标CCD发送探测请求:约10–15ns。

  4. 目标CCD处理探测请求(查找L3标签、准备数据):约5–10ns。

  5. 数据从目标CCD经IOD返回请求者CCD:约15–20ns。

总延迟约为45–70ns,具体取决于IF链路的频率和负载情况。作为对比,同一CCD内部的L3命中延迟约为35–40ns,本地内存访问延迟约为90–120ns。跨CCD一致性延迟介于两者之间,在延迟敏感型应用中可能成为性能瓶颈。

双Socket系统的一致性。EPYC支持双Socket(2P)配置,两个EPYC处理器通过xGMI(Global Memory Interconnect)链路直接互连。xGMI提供了Socket间的缓存一致性和内存访问路径。跨Socket的一致性延迟更高——约为120–180ns——因为数据需要通过xGMI链路在两个处理器封装之间传输。

在双Socket系统中,每个Socket的IOD上的Probe Filter需要追踪本地和远程Socket的缓存状态。当本地Socket的核心需要访问远程Socket上的内存或远程Socket核心的Cache中的数据时,请求通过xGMI链路转发。操作系统通过NUMA感知的内存分配(如Linux的numactl工具)尽量将线程的数据分配在其运行的Socket的本地内存上,以减少跨Socket访问。

性能分析 7 — NUMA效应对应用性能的影响

在EPYC多CCD/多Socket系统中,NUMA(Non-Uniform Memory Access)效应对应用性能的影响非常显著。以下是几种典型场景的性能对比(以本地CCD内L3命中延迟为基准1.0x):

访问场景延迟相对倍数
本地L2命中\sim12 ns0.3x
本地CCD L3命中\sim40 ns1.0x
跨CCD L3命中(同Socket)\sim60 ns1.5x
本地Socket内存\sim100 ns2.5x
跨Socket L3命中\sim150 ns3.8x
跨Socket内存\sim200 ns5.0x

对于内存延迟敏感型应用(如数据库OLTP、键值存储),跨NUMA节点的内存访问可能导致30%–50%的性能下降。因此,EPYC系统的性能调优中,NUMA感知的线程和内存布局是最重要的优化手段之一。Linux内核的NUMA balancing机制(自动将内存页迁移到访问它的核心的本地节点)可以部分缓解NUMA效应,但对于具有复杂数据共享模式的应用,手动的NUMA绑定通常能获得更好的性能。

内存控制器的布局

内存控制器是服务器处理器中最关键的I/O组件之一,其布局和组织直接影响系统的内存带宽、延迟和可扩展性。EPYC的内存控制器布局经历了从Zen 1到Zen 5的显著演进,反映了AMD在Chiplet架构下对内存子系统设计的持续优化。

Zen 1/Naples:分布式内存控制器。第一代EPYC(Naples)采用了4个Die的MCM(Multi-Chip Module)封装,每个Die集成2个DDR4内存通道的控制器,总共提供8个DDR4通道。每个Die的核心优先访问本地Die上的内存控制器(延迟最低),访问其他Die上的内存控制器需要通过Infinity Fabric,延迟显著增加。这种分布式布局创造了4个NUMA域——操作系统需要感知每个核心与内存通道之间的亲和性关系。

Zen 2/Rome和Zen 3/Milan:集中式内存控制器。从Zen 2开始的CCD+IOD Chiplet架构将所有内存控制器集中到IOD上。这一变化带来了重要的统一性改进:所有CCD访问任何内存通道的延迟基本相同(都需要经过IF链路到达IOD上的内存控制器),消除了Naples中因Die位置不同导致的内存延迟不对称性。

Rome(Zen 2 EPYC)的IOD包含8个DDR4内存控制器,每个控制器管理一个72位宽的DDR4通道(64位数据 + 8位ECC)。8个通道的总理论峰值带宽(以DDR4-3200为例)为:

BW=8×8 B×3200 MT/s=204.8 GB/sBW_{\text{总}} = 8 \times 8 \text{ B} \times 3200 \text{ MT/s} = 204.8 \text{ GB/s}

Zen 4/Genoa:12通道DDR5。Genoa将内存通道数从8个增加到12个,并从DDR4升级到DDR5。DDR5的每通道带宽更高(DDR5-4800: 38.4 GB/s/通道 vs DDR4-3200: 25.6 GB/s/通道),加上通道数量增加,总带宽大幅提升:

BW=12×8 B×4800 MT/s=460.8 GB/sBW_{\text{总}} = 12 \times 8 \text{ B} \times 4800 \text{ MT/s} = 460.8 \text{ GB/s}

这是Rome DDR4-3200配置的2.25倍。此外,DDR5引入了On-Die ECC(片上纠错),每个DRAM芯片内部自行纠正单比特错误,再通过系统级ECC提供额外的保护层,这对服务器的可靠性有重要意义。

DDR5的另一个重要变化是通道宽度的调整:DDR4的一个通道为64位数据宽度(加8位ECC),而DDR5将一个物理通道分为两个独立的32位子通道(sub-channel)。每个子通道可以独立发起读写命令,有效地增加了Bank级并行性。EPYC的内存控制器充分利用了这一特性,将两个子通道视为半独立的内存通路进行调度。

内存交织(Memory Interleaving)。EPYC支持多种内存交织粒度,用于平衡各内存通道之间的访问负载。常见的交织方式包括:

  • Cache行交织:连续的64字节Cache行被轮流分配到不同的内存通道。例如,在8通道交织下,地址AA的Cache行分配到通道(A/64)mod8(A / 64) \bmod 8。这种细粒度交织最大化了内存带宽利用率——任何连续的内存访问流都能均匀地分布到所有通道。

  • 页级交织:以4KB或更大的页为单位进行交织。这种粗粒度交织的行级局部性更好(同一页的连续Cache行访问命中同一通道/DRAM bank),但可能导致某些访问模式下的通道负载不均衡。

  • NUMA域级交织:在多Socket系统中,可以选择只在本地Socket的通道间交织(保持NUMA局部性),或跨两个Socket的所有通道交织(最大化带宽但增加平均延迟)。

硬件描述 8 — 内存控制器中的地址哈希

EPYC使用地址哈希(address hashing)来将物理地址映射到内存通道、Bank、Rank和Row。与简单的位截取(bit-slicing)不同,地址哈希使用物理地址中多个位的XOR组合来确定通道号和Bank号。这种哈希方式的目的是打破某些规律性访问模式(如以固定步长遍历数组)可能导致的通道冲突(channel conflict)。

例如,12通道Genoa的通道选择可以使用以下形式的哈希:

channel=(iSaddr[i])mod12\text{channel} = \left(\bigoplus_{i \in S} \text{addr}[i]\right) \bmod 12

其中SS是一组精心选择的地址位索引,\bigoplus表示XOR操作。通过选择合适的SS,哈希函数可以确保:(1)连续Cache行被均匀分布到不同通道;(2)以2的幂次步长(如4KB、2MB)访问的模式也能均匀分布;(3)同一DRAM Row中的连续列访问尽量命中同一Bank,以利用Row Buffer的局部性。

地址哈希的具体配置可以通过BIOS设置调整,高级用户和系统管理员可以根据工作负载的访问模式选择最优的哈希策略。

内存控制器与CCD的拓扑关系。在Genoa(12 CCD + 12通道DDR5)的配置中,12个CCD和12个内存通道在IOD上通过Infinity Fabric的交换结构连接。尽管所有CCD访问任何通道的延迟在理论上是均匀的(都经过IOD的交换结构),但在实际实现中,IOD上内存控制器的物理布局可能导致某些CCD访问某些通道的延迟略低于其他组合。AMD通过Infinity Fabric的交换结构中的缓冲和仲裁逻辑来最小化这种不对称性,但在极高带宽利用率下(如内存带宽密集型HPC应用),微小的延迟差异仍可能被观察到。

图 42.5展示了EPYC Genoa的内存子系统拓扑。

EPYC Genoa的内存子系统拓扑。12个CCD和12个内存控制器通过IOD上的Infinity Fabric交换结构互连。
EPYC Genoa的内存子系统拓扑。12个CCD和12个内存控制器通过IOD上的Infinity Fabric交换结构互连。

内存控制器的调度策略。EPYC的内存控制器内部实现了复杂的请求调度逻辑,以最大化DRAM的利用率和带宽效率。关键的调度策略包括:

  • Row Buffer命中优先(FR-FCFS, First-Ready First-Come-First-Served):如果一个等待中的请求可以命中当前打开的DRAM Row Buffer(即Row Buffer Hit),则优先调度该请求,避免关闭当前Row再打开新Row的延迟开销。Row Buffer Hit的延迟约为tCL(CAS Latency,\sim14ns),而Row Buffer Conflict(需要先关闭再打开)的延迟为tRP + tRCD + tCL(\sim40ns),两者之间的差距约为3倍。

  • Bank级并行:现代DRAM模块包含多个Bank(DDR5通常为16–32个Bank Group),每个Bank可以独立地执行打开Row、读取/写入和关闭Row的操作。内存控制器通过将请求分散到不同的Bank来实现Bank级并行(Bank-Level Parallelism),使得一个Bank的Row激活操作与另一个Bank的数据传输可以重叠。

  • 读写切换优化:DRAM总线在读和写之间切换需要一定的转向延迟(turnaround penalty),通常为几个时钟周期。内存控制器通过批量处理读请求、然后批量处理写请求(write batching)的方式减少读写切换的次数,提高总线利用率。

3D V-Cache技术。值得单独提及的是AMD的3D V-Cache技术——通过三维堆叠(3D stacking)在CCD上方增加一层额外的SRAM Die,将每个CCD的L3 Cache容量从32MB增加到96MB。这项技术首次应用于Milan-X(EPYC 7003X系列),随后扩展到Genoa-X(EPYC 9004X系列)和桌面产品(Ryzen 7 5800X3D、Ryzen 9 7950X3D等)。

3D V-Cache的额外64MB L3位于CCD上方,通过硅通孔(TSV, Through-Silicon Via)与CCD连接。其访问延迟与CCD上原生的32MB L3基本相同(约40ns),因此对软件完全透明——操作系统和应用程序看到的是一个统一的96MB L3 Cache,无需任何修改。

3D V-Cache的实现面临几个关键的工程挑战:

  • 热管理:额外的SRAM Die堆叠在计算Die上方,阻碍了热量从计算Die向散热器的传导。AMD通过优化TSV阵列的分布(TSV本身也是热传导通路)和调整CCD的最高频率来管理热限制。3D V-Cache版本的处理器通常比非V-Cache版本的最高频率低100–200MHz,这是热管理限制的直接体现。

  • 供电网络:额外的SRAM Die需要供电,供电通路通过TSV从CCD的供电网络延伸到SRAM Die。TSV的电阻和电感必须足够低,以确保SRAM Die获得稳定的供电电压。

  • 已知良品Die的选择(Known Good Die, KGD):3D堆叠要求两个Die在堆叠之前都是已知良品——一旦堆叠完成,如果其中一个Die有缺陷,整个堆叠体都必须报废。因此,CCD和SRAM Die在堆叠前都需要进行完整的测试。

在对L3容量敏感的工作负载中,3D V-Cache带来了显著的性能提升。以游戏为例,Ryzen 7 5800X3D(96MB L3)相比Ryzen 7 5800X(32MB L3)在多款游戏中实现了15%–25%的帧率提升。在服务器领域,EDA仿真、关系型数据库和某些科学计算应用也从更大的L3中获益显著。3D V-Cache的成功验证了三维堆叠技术在主流处理器产品中的可行性,为未来更激进的三维集成方案(如将内存直接堆叠在处理器上方)奠定了工程基础。

案例研究 4 — Chiplet架构的产业影响

AMD EPYC的Chiplet架构不仅改变了AMD自身的竞争地位,还对整个半导体产业产生了深远影响。

制造经济性的验证。EPYC以实际产品证明了Chiplet架构在制造成本上的优势。与Intel同期的单片Xeon处理器(如Ice Lake-SP,面积约660 mm2)相比,EPYC的单个CCD面积仅为70–80 mm2,良率显著更高。即使考虑IOD的面积和封装成本,EPYC的总制造成本也低于同核心数的单片设计。这一经济性优势使AMD能够以更低的成本提供更多核心的产品,在性价比上形成竞争优势。

推动行业标准。EPYC的成功推动了行业对Chiplet架构和Die间互连标准化的重视。UCIe(Universal Chiplet Interconnect Express)标准的制定在很大程度上受到了AMD Infinity Fabric和Intel EMIB/Foveros等Die间互连技术的实践经验的启发。UCIe旨在为不同厂商的Chiplet提供统一的互连标准,使得来自不同制造商的Chiplet可以在同一封装中集成——这将进一步推动异构集成(heterogeneous integration)的发展。

设计方法论的变革。Chiplet架构改变了处理器的设计方法论:从"设计一个大Die"转变为"设计多个可复用的小Die并在封装层面集成"。这种模块化方法允许AMD用相同的CCD设计覆盖从4核桌面产品到128核服务器产品的完整产品线——不同产品的差异仅在于CCD数量和IOD配置。这大幅减少了设计团队的规模需求和产品上市时间。

性能分析 8 — 3D V-Cache对不同工作负载的性能影响

3D V-Cache将L3容量从32MB增加到96MB,但其性能收益高度依赖于工作负载的缓存访问特征。可以将工作负载分为三类:

(1)显著受益的工作负载(L3容量敏感型):工作集大于32MB但小于96MB的应用。典型例子包括:

  • 游戏引擎:游戏的纹理元数据、场景图和AI状态数据通常在40–80MB范围内,96MB L3可以容纳大部分数据,避免频繁的内存访问。性能提升15%–25%。

  • EDA仿真:芯片设计仿真的数据结构(如网表、时序图)通常在50–200MB范围内,更大的L3可以缓存更多的热点数据。性能提升10%–20%。

  • 关系型数据库的索引查找:B-tree索引的热点节点可以被更大的L3缓存,减少索引遍历的内存访问次数。

(2)中等受益的工作负载:工作集远大于96MB,但具有明显的时间局部性,使得更大的L3可以缓存更多的近期访问数据。典型例子包括键值存储(如Redis、Memcached)和编译器。

(3)几乎不受益的工作负载:工作集极大且缺乏局部性(如大规模矩阵运算、流式数据处理),或工作集小于32MB(已经完全适配基础L3)。对于这些工作负载,额外的L3容量带来的边际收益接近零。

在EPYC服务器产品中,3D V-Cache版本(如Milan-X、Genoa-X)通常以较低的频率运行(受热限制),因此在非L3敏感型工作负载上性能可能略低于非V-Cache版本。用户在选择产品时需要根据实际工作负载的缓存特征做出权衡。

Zen 1\sim5代际微架构综合对比

为了全面理解Zen系列的演进轨迹,表表 42.8将五代微架构的所有关键参数汇总在一起。这张表是本章分析的最完整参考。

参数Zen 1Zen 2Zen 3Zen 4Zen 5
工艺与频率
制程GF 14nmTSMC 7nmTSMC 7nmTSMC 5nmTSMC 4/3nm
最高频率(桌面)4.0 GHz4.7 GHz4.9 GHz5.7 GHz5.7 GHz
IPC提升 vs 前代\sim15%\sim19%\sim13%\sim16%
前端
解码宽度4-wide4-wide4-wide4-wide4+4-wide
Op Cache2K μ\muop4K μ\muop4K μ\muop6.75K μ\muop>>6.75K
L1 I-Cache64 KB64 KB64 KB64 KB64 KB
分支预测器感知机改进感知机感知机+TAGE感知机+TAGE双通道
BTB\sim2K\sim4K\sim6K\sim12K>>12K
后端
分发宽度6-wide6-wide6-wide6-wide8-wide
ROB192224256320\sim448
整数调度器84929296>>96
整数ALU端口44446
AGU端口33334
BRU端口11112
FP/SIMD通路2×\times128b2×\times128b2×\times128b2×\times128b2×\times256b
存储子系统
L1 D-Cache32 KB/4c32 KB/4c32 KB/4c32 KB/4c32 KB/4c
L2 Cache512 KB/12c512 KB/12c512 KB/12c1 MB/14c1 MB/12c
L3/CCX8 MB16 MB32 MB32 MB32 MB
核心/CCX44888
Load Queue44727288>>88
Store Queue44646464>>64
其他
SMT2-way2-way2-way2-way2-way
AVX-512双泵128b双泵256b
DDRDDR4DDR4DDR4DDR5DDR5
Chiplet

Zen 1\sim5全维度微架构参数对比

案例研究 5 — Op Cache在SPEC CPU上的IPC贡献

Op Cache对IPC的贡献可以通过禁用Op Cache后的性能对比来估算。AMD和独立研究者通过微码修改或性能计数器分析得到了以下估算:

在Zen 4(6.75K Op Cache)上运行SPEC CPU 2017整数子集:

  • Op Cache启用:平均Op Cache命中率\sim88%,前端IPC瓶颈率\sim12%。

  • Op Cache禁用(全部走解码器路径):前端IPC瓶颈率升至\sim25%,IPC下降约8%\sim12%。

Op Cache的IPC贡献来自两个机制:

  1. 延迟消除:Op Cache命中时绕过3\sim4级解码流水线,减少了分支预测失败时的前端重填延迟(从\sim15周期降至\sim11周期)。这一效应在分支密集的代码中尤为显著。

  2. 带宽提升:Op Cache每周期最多输出9条μ\muops(Zen 4),高于解码器的8条μ\muops上限。在指令密集的热循环中,Op Cache可以持续以更高带宽供给后端。

与Intel的DSB(Decoded Stream Buffer,μ\muOp Cache)相比,AMD的Op Cache设计有一个关键差异:AMD在Op Cache miss时fallback到解码器的切换延迟约为2\sim3周期(需要flush Op Cache流水线并启动解码器流水线),而Intel的DSB miss fallback延迟约为1\sim2周期。这一差异使得AMD的Op Cache对"中等代码足迹"工作负载(频繁在Op Cache命中和miss之间切换)更为敏感——AMD通过持续增大Op Cache容量(从2K到6.75K)来减少miss频率,从而规避了这一劣势。

Chiplet架构的良率驱动分析

AMD率先采用Chiplet架构的根本驱动力是良率经济学。以下推导从第一性原理解释了为什么Chiplet在96核以上规模成为必然选择。

假设晶圆的缺陷密度为DD(defects/cm2^2),Die面积为AA(cm2^2),则单Die良率按Poisson模型近似为:

Y=eDA Y = e^{-D \cdot A}

对于TSMC 5nm工艺的成熟良率(D0.08D \approx 0.08 defects/cm2^2),不同Die面积的良率对比:

方案Die面积 (mm2^2)良率每晶圆good die数
单片96核\sim1200e0.08×12=38%e^{-0.08 \times 12} = 38\%不可能^*
CCD (8核)70e0.08×0.7=95%e^{-0.08 \times 0.7} = 95\%\sim800
IOD (6nm)400e0.05×4=82%e^{-0.05 \times 4} = 82\%\sim140

^*1200 mm2^2超过光刻机单次曝光极限(\sim800 mm2^2),物理上不可制造。

组装一个96核EPYC(12个CCD + 1个IOD)的组合良率:

Ysystem=YIOD×YCCD12=0.82×0.9512=0.82×0.54=44%Y_{\text{system}} = Y_{\text{IOD}} \times Y_{\text{CCD}}^{12} = 0.82 \times 0.95^{12} = 0.82 \times 0.54 = 44\%

虽然44%看起来不高,但每个CCD只需70 mm2^2的5nm面积(vs 1200 mm2^2的单片方案——根本造不出来)。而且AMD可以对良率最好的CCD进行分级(binning),将频率最高的CCD用于桌面旗舰产品,频率较低的CCD用于服务器或笔记本产品,进一步提高了整体经济性。

这一良率分析验证了第 52.0 章中将详细讨论的Chiplet设计方法论——当核心数量超过一定阈值(约32\sim64核)时,Chiplet架构在经济性上成为唯一可行的方案。

EPYC双Socket系统的multi-CCD拓扑:每个Socket包含最多12个CCD通过IF连接到中央IOD,两个Socket通过xGMI链路实现跨Socket缓存一致性。总计可达192核心(Turin 2P系统可达256核心)。
EPYC双Socket系统的multi-CCD拓扑:每个Socket包含最多12个CCD通过IF连接到中央IOD,两个Socket通过xGMI链路实现跨Socket缓存一致性。总计可达192核心(Turin 2P系统可达256核心)。

本章小结

本章深入分析了AMD Zen微架构家族从Zen 1到Zen 5的设计演进,涵盖了核心微架构、片上互连和系统级架构三个层面。Zen 1彻底抛弃了Bulldozer CMT架构的五大失败教训——共享前端的带宽腰斩、浮点单元共享的瓶颈、共享L2的争用效应、CMT调度的混乱、以及过度追求多线程而忽视单线程——回归了每核独立资源的经典设计。

在核心微架构层面,Zen 1通过彻底抛弃Bulldozer的CMT架构——具体吸取了共享前端带宽腰斩、浮点单元共享瓶颈、L2争用效应、CMT调度混乱和忽视单线程性能五大教训——构建全新的4-wide解码/6-wide分发乱序核心、引入Op Cache(2K微操作)和优化缓存层次,实现了相对于前代52%的IPC跃升。后续的Zen 4和Zen 5在此基础上持续演进:Zen 4将ROB扩大到320表项、L2 Cache倍增到1MB/核、Op Cache增至6.75K微操作,并以双泵128位策略实现了AVX-512支持——这种策略避免了Intel原生512位实现的降频问题,在混合工作负载中表现更为均衡;Zen 5将分发宽度提升至8-wide、ROB进一步扩展至约448表项,并将SIMD执行通路加宽到256位。

在CCX/CCD组织层面,从Zen 1的4核CCX(8MB L3)到Zen 2的双CCX CCD(2×\times16MB L3),再到Zen 3的统一8核CCX(32MB L3),这一演进路径体现了AMD对核间数据共享延迟的持续优化。Zen 3的统一CCX消除了CCD内部的跨CCX延迟,将L3的有效共享范围从4核扩大到8核,对游戏和多线程应用的性能提升贡献了5%–8%的IPC改善。

在Op Cache的设计方面,从Zen 1的2048项到Zen 4的6750项,容量增长了3.3倍。Op Cache的映射窗口从32字节扩大到64字节,Way利用率从约70%提升到约80%以上。这些改进使得越来越多的热点代码可以从Op Cache中获取μ\muops,绕过耗时耗能的x86解码器,是Zen系列前端效率持续提升的关键技术之一。

在片上互连层面,Infinity Fabric的引入建立了统一的数据传输和一致性通信基础设施。IF的SDF组件提供了高带宽、低延迟的数据通路,其频率与内存控制器锁定的设计简化了接口同时创造了一条清晰的性能调优路径。

在系统级架构层面,EPYC的CCD+IOD Chiplet架构是最具影响力的创新。通过将计算Die和I/O Die分离制造、用不同工艺节点优化各自的需求,EPYC实现了从32核到128核的规模扩展,同时保持了合理的制造成本和良率。多Die之间的MOESI一致性协议、Probe Filter目录和Infinity Fabric交换结构共同确保了跨Die通信的正确性和效率。

从处理器设计的方法论角度看,Zen微架构家族的成功提供了几条重要的经验:

  1. 均衡设计优于极端设计:微架构创新不一定需要追求每个维度的绝对最优。Zen 4的AVX-512双泵策略虽然峰值吞吐不如Intel的原生512位实现,但在整体系统表现上更为均衡——不降频意味着混合负载的性能更加可预测。类似地,Zen 1选择192表项ROB而非更大的规模,在面积和时序约束下获得了最佳的性价比。

  2. 封装级创新与工艺进步同等重要:Chiplet架构证明了封装级的创新可以成为与工艺进步同等重要的性能和经济性驱动力。当单片Die的面积受到光刻极限和良率限制时,Chiplet提供了一条继续扩展核心数量的可行路径。混合工艺节点的使用(计算Die用先进节点、IO Die用成熟节点)进一步优化了成本结构。

  3. 片上互连是系统性能的基础设施:Infinity Fabric的设计是多核/多Die系统性能的关键基础设施,其重要性不亚于核心微架构本身。IF的频率与内存锁定设计、SDF的带宽规划和Probe Filter的目录效率,共同决定了系统级的性能上限。

  4. 模块化复用降低设计成本:用相同的CCD设计覆盖从4核桌面到128核服务器的完整产品线,大幅减少了设计、验证和流片的投入。这种模块化方法使AMD能够以相对精简的设计团队支撑庞大的产品矩阵,在竞争中获得了结构性的成本优势。

  5. 渐进式微架构改进的累积效应:Zen系列的每一代IPC提升在13%–19%之间,单看每一代并不是革命性的变化。但五代累积下来,Zen 5的IPC相对于Zen 1提升了约80%–90%。这种持续、稳定的改进节奏——在工艺、微架构和系统架构三个层面同时推进——是长期竞争力的核心来源。

Zen系列的执行端口演进

AMD Zen系列的执行端口组织在每一代中都有重要的调整,反映了对工作负载特征的持续分析和响应。

Zen 1的执行端口布局。Zen 1的后端分为独立的整数和浮点/SIMD执行域,两者拥有各自的调度器和执行端口:

  • 整数域:6个执行端口——ALU0(加/减/逻辑)、ALU1(加/减/逻辑)、ALU2(加/减/逻辑/乘法)、ALU3(加/减/逻辑/除法)、AGU0(地址生成)、AGU1(地址生成)。ALU0和ALU1是简单的单周期整数运算端口,ALU2增加了整数乘法能力(3周期延迟),ALU3增加了整数除法(可变延迟)。两个AGU端口负责所有load和store操作的地址计算。

  • 浮点/SIMD域:4个执行端口——FMAC0(浮点乘加/128位)、FMAC1(浮点乘加/128位)、FADD/CVT(浮点加法/转换)、FMISC/STORE(浮点杂项/Store数据路径)。两个128位FMAC单元可以拼合执行一条256位的AVX/AVX2 FMA操作,每周期完成。

Zen 3的执行端口改进。Zen 3在整数域增加了第4个ALU端口(从3个增加到4个),使整数计算的峰值吞吐从3 ops/周期提升到4 ops/周期。这一扩展对分支密集和整数运算密集的代码效果显著。Zen 3还将浮点FADD的延迟从4周期降低到3周期,改善了浮点加法依赖链的吞吐。

Zen 4的端口调整。Zen 4的最大变化是为支持AVX-512对浮点/SIMD域的重组。AVX-512的掩码操作需要额外的执行逻辑,Zen 4在浮点域增加了掩码处理单元。同时,Zen 4将部分浮点操作(如浮点转整数、浮点比较等)从FADD端口迁移到FMISC端口,释放了FADD端口的带宽给纯浮点加法操作。

Zen 5的端口大幅扩展。Zen 5的后端宽度从Zen 4的6-wide扩展到8-wide分发,相应地增加了更多的执行端口。据公开信息,Zen 5在整数域增加了第5个和第6个ALU端口(共6个ALU端口),在浮点域将SIMD数据通路从128位拓宽到256位——这意味着256位AVX2操作可以在单个端口上一个周期完成(而非之前需要两个128位端口拼合)。

执行端口Zen 1Zen 3Zen 4Zen 5
整数ALU4446
整数MUL1112
整数DIV1111
AGU (Load/Store)3334
分支1112
浮点FMA2×\times128b2×\times128b2×\times128b2×\times256b
浮点ADD1×\times128b1×\times128b1×\times128b1×\times256b
总端口数\sim10\sim10\sim10\sim14

Zen系列执行端口数量的演进

Zen 5的端口数量从约10个增加到约14个,增幅达40%。这一扩展需要相应扩大调度器容量和旁路网络。更多的端口意味着唤醒逻辑需要比较更多的结果标签,选择逻辑需要在更多端口之间仲裁——这些都是面积和时序的重大挑战。AMD通过TSMC 4nm/3nm工艺的晶体管密度提升来吸收这些开销。

设计提示

AMD在Zen系列中一直保持整数和浮点执行域的物理分离——两个域拥有独立的调度器和物理寄存器文件。这种分离设计与Intel的统一调度器形成对比。分离设计的优势是每个调度器的规模较小,唤醒-选择逻辑更快;劣势是在整数或浮点工作负载严重不均衡时,一个域的资源可能闲置。AMD的分析表明,在实际工作负载中,整数和浮点指令的比例虽有波动,但平均分配约为70:30(整数:浮点),分离设计的资源浪费不超过5%–10%。更重要的是,分离设计使得AMD可以在不影响整数调度器时序的前提下大幅扩展浮点调度器(如为AVX-512增加容量),这种模块化的灵活性在代际演进中非常有价值。

Zen系列的存储子系统演进

存储子系统是Zen系列每一代IPC提升的重要贡献者。从Zen 1到Zen 5,AMD在Cache层次、预取器和Store-to-Load Forwarding等方面都进行了持续优化。

L1 DCache的演进。Zen 1的L1 DCache为32KB 8路组相联,延迟4周期。这一配置从Zen 1到Zen 5保持不变——L1 DCache的容量被认为在32–64KB的范围内已经达到了面积-命中率的最佳平衡点。但Zen 4和Zen 5在L1 DCache的带宽和预取效率上进行了改进:

  • Zen 4:L1 DCache每周期支持2个load + 1个store的带宽(与Zen 1相同),但改进了Store-to-Load Forwarding的覆盖范围——支持更多的部分重叠转发场景。

  • Zen 5:L1 DCache的load端口可能增加到3个(配合更宽的后端),使每周期的load吞吐从2提升到3。这需要L1 DCache的SRAM实现从2读1写扩展到3读1写,面积和功耗增加约30%–40%。

L2 Cache的容量增长。L2 Cache是Zen系列中变化最显著的Cache层级:

  • Zen 1/2/3:512KB/核,8路组相联,12周期延迟。采用写回+非包含策略。

  • Zen 4:1MB/核,8路组相联,14周期延迟。容量翻倍带来的命中率提升约15%–20%(在SPEC CPU 2017整数基准上),但延迟增加了2个周期(从12到14)。延迟增加的原因是更大的SRAM阵列需要更长的字线和位线,信号传播时间增加。

  • Zen 5:保持1MB/核,但通过工艺缩小和SRAM设计优化将延迟降回12–13周期,在保持大容量的同时改善了延迟。

预取器的进化。AMD在每一代中都改进了硬件预取器的精度和激进程度:

  • Zen 1:基本的stride预取器和next-line预取器。stride预取器检测固定步长的访问模式,next-line预取器在每次L2 miss时预取相邻的Cache行。

  • Zen 2/3:增加了stream预取器,可以同时追踪多个独立的数据流。stream预取器对连续内存访问模式(如数组遍历、矩阵运算)效果显著。

  • Zen 4:引入了基于PC的预取器(IP prefetcher),为每个load指令独立记录历史访问步长,实现个性化预取。这对于不同load指令访问不同数据结构(各有不同步长)的代码非常有效。

  • Zen 5:进一步增强预取器的"前瞻距离"(look-ahead distance),在检测到数据流后更早地发起预取请求,以补偿DDR5更高的绝对延迟。同时增加了对不规则访问模式的预取支持——如链表遍历中的"指针预取"(pointer prefetch),通过分析load指令的结果(指针值)来预测下一次访问的地址。

性能分析 9 — Zen系列Cache层次对SPEC CPU 2017的量化影响

以SPEC CPU 2017整数子集(SPECint2017)为基准,分析Cache层次改进对IPC的贡献:

  • Zen 1\rightarrowZen 2(L3从8MB/CCX增至16MB/CCX):L3容量翻倍使SPECint的平均L3命中率从约85%提升到约90%,贡献约3%–5%的IPC提升。

  • Zen 2\rightarrowZen 3(统一8核CCX,L3从2×162\times16MB增至统一32MB):L3统一使有效容量翻倍(从单核视角),命中率从约90%提升到约93%,贡献约4%–6%的IPC提升。同时消除了跨CCX延迟,额外贡献约2%–3%。

  • Zen 3\rightarrowZen 4(L2从512KB增至1MB):L2命中率从约88%提升到约92%,减少了对L3的访问压力,贡献约3%–5%的IPC提升。

  • Zen 4\rightarrowZen 5(预取器改进 + L2延迟优化):预取器的改进将有效内存延迟降低约15%–20%,贡献约3%–4%的IPC提升。

累计来看,从Zen 1到Zen 5的Cache层次改进总共贡献了约15%–23%的IPC提升——约占总IPC提升(80%–90%)的20%–25%。其余75%–80%的IPC提升来自分支预测改进、后端宽度扩展、执行端口增加等微架构优化。

Zen微架构的演进历程也为处理器设计领域提供了一个重要的参考案例:在技术积累和团队能力达到临界点之后,一个全新的微架构设计可以在短短几年内从落后者变为引领者。Zen 1的成功并非偶然——它建立在AMD数十年的x86处理器设计经验、对Bulldozer失败教训的深刻反思,以及Jim Keller等关键架构师的技术洞察力之上。从Zen 1到Zen 5,每一代的改进都体现了对工作负载特征的深入理解和对工艺能力的精准利用。这种"以工作负载为导向、以工程可行性为约束"的设计方法论,值得每一位处理器设计者认真学习和思考。

Zen系列的分支预测器深度分析

AMD Zen系列的分支预测器是其IPC竞争力的核心来源之一。从Zen 1开始,AMD选择了与Intel不同的分支预测器基础架构——基于感知机(perceptron)的预测器而非传统的基于计数器的预测器。

感知机预测器的基本原理。感知机预测器由Jimenez和Lin于2001年提出,其核心思想是将分支预测问题建模为一个线性分类问题。对于每条分支指令,预测器维护一个权值向量w=(w0,w1,,wn)\mathbf{w} = (w_0, w_1, \ldots, w_n),其中nn是使用的历史长度。预测过程如下:

  1. 计算全局历史向量h=(h1,h2,,hn)\mathbf{h} = (h_1, h_2, \ldots, h_n)中各位(hi{1,+1}h_i \in \{-1, +1\},表示第ii次前的分支是taken还是not-taken)与权值的加权和:
y=w0+i=1nwihiy = w_0 + \sum_{i=1}^{n} w_i \cdot h_i
  1. 如果y0y \geq 0,预测taken;否则预测not-taken。

  2. 在分支结果确定后,如果预测错误或y<θ|y| < \theta(置信度不足),更新权值:

wiwi+thi,i=1,,nw_i \leftarrow w_i + t \cdot h_i, \quad i = 1, \ldots, n

其中t{1,+1}t \in \{-1, +1\}是分支的实际方向。

感知机预测器的关键优势是可以高效利用很长的历史——权值向量的存储随历史长度nn线性增长(O(n)O(n)),而传统的gshare预测器的存储随历史长度指数增长(O(2n)O(2^n))。这使得感知机预测器可以使用93位甚至更长的历史,捕获远距离的分支相关性。

Zen 1中感知机预测器的实现。Zen 1的分支预测器是一个感知机-TAGE混合预测器。感知机作为主预测器处理大多数分支,TAGE作为辅助预测器处理感知机难以捕获的模式(如某些具有短期上下文依赖的分支)。两个预测器的结果通过一个选择器(meta-predictor)进行融合——选择器根据历史记录判断在当前上下文下哪个预测器更准确,并输出更可靠的预测结果。

这种混合策略结合了感知机的长历史利用能力和TAGE的短历史精确性。在CBP(Championship Branch Prediction)竞赛的基准上,这种混合预测器的MPKI比单独使用感知机或TAGE都要低10%–15%。

从Zen 1到Zen 5的预测器演进。AMD在每一代中都增大了分支预测器的存储容量和改进了训练算法:

  • Zen 1:基础感知机-TAGE混合预测器,总存储约24–32KB。BTB约2K表项。

  • Zen 2:增大BTB到约4K表项,改进间接分支预测器。总存储约32–40KB。

  • Zen 3:进一步增大TAGE表容量,引入改进的训练算法以加速预测器对新分支模式的适应。这一代的分支预测改进被认为是Zen 3实现19%IPC提升的重要贡献者之一(约贡献了5%–7%的IPC提升)。

  • Zen 4:显著增大BTB到约8K–12K表项,改进方向预测器的TAGE组件。据分析引入了更长的全局历史(可能从93位增加到128位以上)。RAS深度增加以支持更深的调用链。

  • Zen 5:引入双通道预测器(dual-channel predictor),在含有大量短基本块的代码中每周期产生两个预测。预测器总存储估计超过64KB,方向预测在SPEC CPU 2017上的MPKI降至约5.2(vs Zen 1的8.2)。

设计提示

AMD选择感知机作为分支预测器的基础架构,反映了公司在分支预测研究上的独特积累。感知机预测器最早由UT Austin的Daniel Jimenez提出,而AMD在2012年前后积极与学术界合作,将感知机预测器的最新研究成果融入Zen微架构的设计中。这种"学术研究到工业实践"的快速转化,是Zen分支预测器性能领先的关键原因之一。

相比之下,Intel的分支预测器传统上基于计数器(如TAGE/PHT风格),不使用感知机。两种方法各有优劣:感知机在利用超长历史方面有天然优势,但其求和运算的关键路径较长(需要nn次乘加操作);TAGE在短历史精确匹配方面更高效,但存储效率随历史长度下降。AMD和Intel分别沿着各自的技术路线持续优化,最终在预测精度上达到了类似的水平——两者在SPEC CPU 2017上的MPKI差距通常不超过10%。

Infinity Fabric的演进与系统级影响

Infinity Fabric(IF)是AMD在Zen架构中引入的统一互连协议,承担了核心间、Die间和Socket间的所有通信。从Zen 1到Zen 5,IF经历了多次关键演进。

Zen 1的IF基础架构。Zen 1的Infinity Fabric由两个核心组件构成:

  • SDF(Scalable Data Fabric):负责数据传输的高带宽通路。SDF提供了每方向每周期16字节的带宽,运行在与内存控制器相同的频率(FCLK = MCLK)。

  • SCF(Scalable Control Fabric):负责缓存一致性请求、中断传递和配置管理等控制消息的传输。SCF的带宽较窄但延迟更低,优先于SDF处理延迟敏感的控制消息。

FCLK-MCLK锁定与解耦。Zen 1中IF的频率(FCLK)与内存控制器频率(MCLK)锁定为1:1关系。这意味着IF的带宽与内存带宽同步增长——使用更高频率的DDR4内存自动获得更高的IF带宽。然而,这也带来了限制:如果用户安装了低频内存(如DDR4-2400),IF的带宽也被锁定在较低水平,即使CPU核心需要更高的核间通信带宽。

Zen 2引入了FCLK-MCLK解耦的选项——用户可以将FCLK设置为MCLK的倍数或独立频率。但解耦会引入额外的延迟(约5–10ns),因为FCLK和MCLK之间的数据需要经过异步FIFO进行时钟域交叉。在实践中,大多数用户仍选择1:1锁定模式以获得最低延迟。

Zen 4的IF带宽提升。Zen 4将SDF的通路宽度从16字节/周期扩展到32字节/周期,IF带宽翻倍。这一提升是为了匹配DDR5内存的更高带宽——DDR5-4800的单通道带宽(38.4 GB/s)远高于DDR4-3200(25.6 GB/s),IF需要更高的带宽来避免成为瓶颈。

IF对NUMA拓扑的影响。在EPYC服务器处理器中,IF的拓扑直接决定了系统的NUMA特征。AMD通过以下方式管理NUMA:

  • NPS(NUMA Per Socket)配置:EPYC支持NPS1(整个Socket为一个NUMA节点)、NPS2(Socket内分为2个NUMA节点)和NPS4(4个NUMA节点)。不同的NPS配置影响了内存交织的粒度和核心到内存通道的亲和性。

  • NPS1模式:所有CCD共享所有内存通道,地址在所有通道间交织。这提供了最大的内存带宽(因为任何核心可以使用任何通道),但跨Die通信的延迟变化较大(不同CCD到不同内存通道的延迟不同)。

  • NPS4模式:将Socket分为4个NUMA域,每个域内的CCD只能优先访问相邻的内存通道。这降低了平均内存延迟(因为每个核心优先使用最近的通道),但限制了每个核心可用的内存带宽。

NPS配置的选择取决于工作负载特征:HPC和大规模并行计算通常受益于NPS1(最大带宽),而延迟敏感的数据库和缓存系统通常受益于NPS4(最低延迟)。

性能分析 10 — Infinity Fabric频率调优对性能的影响

IF频率的调优是AMD平台性能优化的重要手段。以Zen 4 Ryzen 7000系列为例:

  • DDR5-4800 + FCLK 2400MHz(1:1锁定):L3访问延迟约42ns,跨CCD通信延迟约75ns。这是默认配置,提供了最佳的延迟和带宽平衡。

  • DDR5-6000 + FCLK 2000MHz(FCLK解耦):FCLK低于MCLK的一半。虽然内存带宽更高(DDR5-6000 vs DDR5-4800),但FCLK的降低导致IF带宽降低,L3访问延迟增加到约48ns(增加14%),跨CCD延迟增加到约85ns(增加13%)。净效果取决于工作负载:内存带宽受限的应用受益于更高的内存频率,但延迟敏感的应用(如游戏)可能因为更高的L3延迟而性能下降。

  • DDR5-6000 + FCLK 2000MHz(FCLK-MCLK 1:1锁定,超频FCLK):如果能将FCLK超频到3000MHz以匹配DDR5-6000,可以同时获得高带宽和低延迟。但FCLK的超频受限于Infinity Fabric的物理设计——大多数Zen 4处理器的FCLK上限约为2100–2200MHz,超过此频率可能导致系统不稳定。

这一调优案例说明了IF频率与内存频率之间的复杂交互——不存在对所有工作负载都最优的单一配置。AMD在BIOS中提供了丰富的IF/内存频率和时序调优选项,允许高级用户根据具体需求进行精细调整。

Zen系列的功耗管理创新

AMD在Zen系列中引入了多项功耗管理创新,使其在能效方面保持竞争力。

Precision Boost与Precision Boost Overdrive。AMD的Precision Boost技术允许处理器在功耗和温度限制内动态调整每个核心的频率。与Intel的Turbo Boost类似,但AMD的实现粒度更细——频率调整步长为25MHz(vs Intel的100MHz),允许更精细的功耗-性能权衡。Precision Boost 2(从Zen+开始)引入了工厂预设的频率-电压曲线,使每个核心可以根据其硅片质量(silicon quality)独立优化频率和电压。

CPPC(Collaborative Processor Performance Control)。AMD实现了ACPI CPPC接口,允许操作系统向处理器传达性能需求的精细信息。CPPC支持两个关键参数:

  • Desired Performance:操作系统期望的性能水平(0–255的标量值)。

  • Energy Performance Preference:能效偏好(0=最高性能,255=最低功耗)。

处理器的电源管理单元(SMU)根据这两个参数加上实时的热和功耗状态,决定每个核心的工作频率和电压。这种硬件-软件协作的方式比纯软件的频率管理(如Linux的cpufreq governor)更高效,因为SMU可以在微秒级别响应频率调整请求,而操作系统的频率调整通常在毫秒级别。

CCD级的电源管理。在EPYC的Chiplet架构中,每个CCD可以独立进入深度休眠状态(类似于Intel的Package C-state)。当一个CCD上的所有8个核心都空闲时,整个CCD(包括其L3 Cache和IF端口)可以被关闭电源,功耗降至接近零。当需要唤醒时,CCD需要约50–100微秒才能恢复到全速运行——在此期间,IOD上的工作负载监控逻辑检测到新的任务需求并触发CCD唤醒。

这种CCD级的电源管理使得EPYC在低负载时可以关闭大部分CCD,仅保留少量CCD处理轻量级任务。例如,一个96核的Genoa处理器在低负载时可能只启用2个CCD(16个核心),其余10个CCD完全关闭,功耗从满载的约350W降低到约30–50W。

Zen系列的专家视角

设计提示

专家洞察1:Zen的成功是系统性的,而非某个单一创新。分析Zen系列的演进历程,一个关键观察是:没有任何一个单一特性可以解释Zen的成功。Op Cache贡献了约8%的IPC,统一CCX贡献了约6%,更大的ROB贡献了约3%——这些改进单独来看都不是革命性的。但Zen的成功在于每一代在所有维度上同时进步:前端宽度、后端深度、Cache容量、分支预测精度、互连带宽。五代累积下来,IPC提升达80%\sim90%。这种"持续的全面改进"策略要求设计团队在每一代中不遗漏任何一个可以改进的维度——这是工程管理上的极大挑战,也是Zen团队最大的技术功绩。

设计提示

专家洞察2:Chiplet架构的真正革命不是技术,而是商业模式。从纯技术角度看,Chiplet并不比单片设计更优越——跨Die的通信延迟更高,功耗更大,封装更复杂。Chiplet的真正革命在于它改变了处理器的商业模式:用一个CCD设计(一次流片成本约5000万\sim1亿美元)覆盖从4核笔记本(1个CCD)到128核服务器(16个CCD)的全部产品线。这使AMD能够用Intel十分之一的设计团队规模维持同等的产品覆盖度,将每颗芯片的分摊研发成本降低到竞争对手的几分之一。这一成本优势被直接转化为更具竞争力的定价,是AMD在服务器市场份额从<<1%增长到>>20%的关键驱动力。

前向桥接——ARM Cortex-X系列的对比。第 43.0 章将分析ARM Cortex-X系列微架构——另一条追求极致单线程IPC的设计路线。与Zen系列形成有趣对比的是:ARM Cortex-X系列(X1/X2/X3/X4/X925)采用了比Zen更激进的前端宽度(6\sim10-wide解码)和更大的ROB(>>400项),但受限于较窄的SIMD数据通路(128位 NEON/SVE)和较小的L2 Cache(256KB\sim1MB)。两条设计路线的差异反映了x86和ARM ISA在指令密度、解码复杂度和内存访问模式上的根本差异——理解这些差异,有助于建立对"高性能乱序核心"设计空间的全面认知。

正文与图片:CC BY-NC-SA 4.0 · 本仓库少量站点配置代码:MIT