Skip to content

Cluster结构

当旁路网络增长到6-wide以上时,物理设计变得不可行——72条旁路路径的4608根数据线无法在一个时钟周期内完成信号传播。解决方案:将执行单元分成多个Cluster,Cluster内全旁路(低延迟),Cluster间额外1周期延迟。这不是"优化",而是物理约束迫使的设计妥协。没有Cluster化,就不会有今天的6-wide、8-wide超标量处理器。

从本书的统一视角看——处理器设计的本质是在有限的晶体管预算和功耗约束下,通过投机和并行的层层叠加来逼近指令吞吐率的理论上限——Cluster结构是在并行的物理约束下实施的分治策略。全局的旁路网络是实现ILP的理想手段,但导线延迟和布线面积为其设定了物理上限。Cluster化通过局部化通信来突破全局互连的物理限制:每个Cluster内保留完整的并行能力(全旁路),Cluster间以最小代价(1周期额外延迟)交换数据。这种"局部并行 + 全局松耦合"的层次化结构,正是在物理约束下逼近理论吞吐率极限的工程答案。

第 34.0 章中,我们详细讨论了旁路网络(bypass network)的设计——它是保证指令间数据快速传递、避免流水线气泡的关键机制。然而,我们也看到了一个残酷的现实:旁路网络的复杂度随着执行端口数量的增长呈二次方增长。对于一个拥有4个执行端口的处理器,全连接旁路网络需要4×4=164 \times 4 = 16条旁路通路,每条通路涉及多位(64位或更宽)的数据多路选择器(MUX),这在物理实现上虽然紧张但仍然可行。然而,当处理器发射宽度达到6-wide、8-wide甚至更宽时,旁路网络的导线数量、MUX扇入和信号传播延迟将急剧膨胀,最终超过单个时钟周期所能容纳的范围。

分簇(Clustering)技术正是为了解决这个问题而诞生的。其核心思想极为直接:既然全连接旁路网络在宽发射处理器中不可行,那么就不要全连接——将执行单元划分为若干个(Cluster),每个Cluster内部保持完整的旁路网络,Cluster之间只提供延迟更高但数量有限的互联通路。这种设计以少量的跨Cluster通信延迟为代价,换取了旁路网络物理实现的可行性和关键路径的改善。

分簇并非一种理论上的折衷方案——它是几乎所有宽发射超标量处理器的必备技术。从1998年DEC Alpha 21264的经典双Cluster整数执行引擎,到2023年Apple M3 Firestorm核心的超宽执行端口布局,再到AMD Zen 5的多端口组织,分簇思想以各种形式贯穿了25年的高性能处理器设计历史。本章将系统性地讨论Cluster的动机、发射队列的分簇组织、旁路网络的分簇设计,以及真实处理器中的Cluster实现案例。

Cluster的动机

回顾第 3.0 章中关于导线延迟的讨论:在5 nm工艺下,1 mm长的顶层金属导线延迟约为60\sim80 ps,已接近单个时钟周期的40%。第 34.0 章则量化了旁路网络的O(N2)O(N^2)增长——6端口处理器需要84条旁路通路和5376根数据导线。当这些导线必须跨越整个执行区域(\sim1 mm)时,信号传播延迟将超出单周期预算。正是这一物理现实催生了Cluster技术。值得一提的是,第 40.0 章中将要讨论的Alpha 21264(1998年)是商业处理器中首个全面采用Cluster架构的设计,其双Cluster整数执行引擎成为后续所有宽发射处理器的设计范本。

在深入Cluster结构的具体设计之前,我们需要透彻理解为什么分簇是必要的——不仅仅是"导线太多"这一笼统的说法,还要量化分析全连接旁路网络在宽发射处理器中面临的物理极限。

宽发射处理器的布线问题

在一个WW-wide的超标量处理器中,每个执行端口可能需要从任何其他执行端口接收旁路数据。假设处理器有PP个执行端口,每个端口有SS个源操作数输入(通常S=2S = 2),则每个执行端口的操作数选择MUX需要从以下来源中选择数据:

  • PP条旁路通路(来自PP个执行端口的当拍结果)。

  • 物理寄存器文件的读端口(1\sim2个)。

  • 对于多周期指令,可能还有来自不同流水级的旁路。

仅考虑执行端口之间的单拍旁路,操作数选择MUX的扇入为P+1P+1PP条旁路加1个寄存器文件读端口)。整个旁路网络的数据总线数量为P×S×(P+1)P \times S \times (P+1)条64位总线——每条总线都是64根并行的金属导线。

性能分析 1 — 全连接旁路网络的规模增长

考虑不同发射宽度下全连接旁路网络的规模(假设每个端口2个源操作数,数据宽度64位):

执行端口数PPMUX扇入旁路通路总数64位导线总数
45402,560
67845,376
891449,216
101122014,080
121331219,968

从4端口到8端口,旁路通路数量增长了144/40=3.6144/40 = 3.6倍,而端口数量仅翻了一倍。到12端口时,旁路通路已接近8端口时的2.2倍。这种超线性增长意味着,仅仅通过增加金属层或优化布局来"硬扛"宽发射处理器的旁路网络很快就会走到物理极限。

布线面积的约束。旁路网络中的每条64位数据通路需要64根金属导线并行布线。在先进工艺节点(7 nm及以下),最小金属间距约为20\sim30 nm,但长距离信号通常使用高层金属(M5以上),其线宽和间距约为40\sim80 nm。即使采用80 nm的间距,一条64位总线也至少需要64×80nm5.12μm64 \times 80\,\text{nm} \approx 5.12\,\mu\text{m}的布线宽度。当旁路通路数量达到100条以上时,仅旁路网络的布线就需要超过500 μ\mum的专用金属通道——这在执行单元的物理布局中是极为奢侈的。

MUX延迟的约束。更严重的问题是MUX延迟。操作数选择MUX位于执行流水线的关键路径上——它必须在指令开始执行之前完成选择。一个NN:1的MUX的延迟近似为O(logN)O(\log N)级门延迟。当NN从5增长到13时,MUX延迟从约3级门延迟增长到约4\sim5级门延迟。在一个5 GHz处理器中(周期200 ps),每级门延迟约为12\sim15 ps,多出的1\sim2级门延迟意味着15\sim30 ps的额外延迟——这足以使关键路径违反时序约束,或者迫使设计者降低时钟频率。

功耗的约束。旁路网络的每条总线在每个周期都需要被驱动——即使数据未被任何执行端口使用。在8-wide处理器中,旁路网络的动态功耗可以占到执行引擎总功耗的15%\sim25%。更宽的处理器中这个比例还会进一步增大。

设计提示

在处理器设计中,连线的延迟和面积往往比逻辑门本身更加关键。随着工艺缩小,逻辑门延迟持续降低,但连线延迟并未同比缩小——在某些先进节点上,连线延迟甚至出现了退化。旁路网络是连线密集型结构的典型代表,其设计在很大程度上受布线资源而非逻辑资源的约束。分簇的本质就是通过减少必须长距离布线的旁路通路数量,将布线问题控制在物理可行的范围内。

6-wide以上处理器全连接旁路的物理不可行性

前面的数据给出了一般性的规模增长趋势,但要真正理解"物理不可行"意味着什么,需要用具体数值进行端到端的推导。本小节以一个8-wide处理器为例,量化论证全连接旁路网络在现代工艺下面临的三重瓶颈。

布线通道预算的推导

考虑一个8-wide整数执行引擎,拥有8个可以产生64位结果的执行端口。全连接旁路意味着每个端口的操作数MUX需要接纳来自其余7个端口的旁路加上至少1个寄存器文件读端口,即MUX扇入为9。旁路通路总数为P×(P1)=8×7=56P \times (P-1) = 8 \times 7 = 56条单向通路。每条通路承载64位数据加上6\sim8位物理寄存器标签(用于旁路匹配验证),共约72位。以5 nm工艺的M4/M5金属层为例,最小间距(half pitch)约为24 nm,但考虑到信号完整性和串扰的工程裕量,实际可用间距约为50 nm。每条72位总线的宽度为:

Wbus=72×50nm=3.6μmW_{\text{bus}} = 72 \times 50\,\text{nm} = 3.6\,\mu\text{m}

56条通路的总布线宽度为:

Wtotal=56×3.6μm=201.6μmW_{\text{total}} = 56 \times 3.6\,\mu\text{m} = 201.6\,\mu\text{m}

这仅是单层金属上的宽度。如果使用两层金属(M4和M5)分别走水平和垂直方向,每层大约需要100 μ\mum。然而,在执行引擎的物理版图中,旁路网络并非唯一的布线需求——时钟树、电源网格、寄存器文件的读写端口数据线、唤醒网络的标签广播线等都在争抢同一片布线空间。在典型的高性能核心中,执行引擎区域的宽度约为400\sim600 μ\mum(5 nm工艺),旁路网络独占200 μ\mum意味着它消耗了30%\sim50%的布线通道——这在物理设计上几乎不可接受。

MUX关键路径的推导

9:1的操作数MUX通常用两级逻辑实现:第一级是4:1或3:1的子MUX,第二级是3:1或2:1的合并MUX。在5 nm FinFET工艺中,每级MUX约为2个FO4延迟。FO4延迟在5 nm下约为6\sim8 ps,因此9:1 MUX的延迟约为2×2×7ps=28ps2 \times 2 \times 7\,\text{ps} = 28\,\text{ps}

旁路通路上的完整关键路径包括:

  1. 源FU的输出寄存器\to旁路驱动器:约10 ps。

  2. 旁路导线传播:取决于物理距离,8个FU跨度约300\sim500 μ\mum,对应30\sim60 ps(含中继缓冲器)。

  3. 目标FU的操作数MUX:约28 ps。

  4. MUX输出到ALU输入的建立时间:约8 ps。

总延迟约为10+45+28+8=91ps10 + 45 + 28 + 8 = 91\,\text{ps}。对于一个5 GHz处理器(周期200 ps),旁路通路消耗了约45%的周期预算。考虑到ALU本身的执行延迟(约60\sim80 ps),留给旁路的预算应该在100\sim120 ps以内。这意味着8端口全连接旁路已经触及了单周期旁路的极限

相比之下,如果将8个FU分成2个Cluster(每个Cluster 4个FU),每个Cluster的MUX扇入降为5:1。5:1 MUX仅需约20 ps延迟,且Cluster内部的旁路导线距离缩短到150\sim250 μ\mum,导线延迟约15\sim30 ps。总延迟约为10+22+20+8=60ps10 + 22 + 20 + 8 = 60\,\text{ps}——比全连接方案减少了约30 ps,为时序收敛提供了充裕的裕量。

功耗的量化

旁路网络的动态功耗主要来自两部分:MUX的开关功耗和导线的充放电功耗。导线功耗与导线长度和翻转率成正比:

Pwire=αCwireVDD2fP_{\text{wire}} = \alpha \cdot C_{\text{wire}} \cdot V_{DD}^2 \cdot f

其中α\alpha是翻转率(约0.15\sim0.25),CwireC_{\text{wire}}是导线电容(约0.2\sim0.3 fF/μ\mum),VDDV_{DD}约0.75 V,f=5GHzf = 5\,\text{GHz}。对于8端口全连接旁路的56条通路,总导线长度约为56×400μm=22.4mm56 \times 400\,\mu\text{m} = 22.4\,\text{mm}。估算总导线功耗约为:

Pwire0.2×0.25fF/μm×22400μm×(0.75)2×5×1093.15mWP_{\text{wire}} \approx 0.2 \times 0.25\,\text{fF}/\mu\text{m} \times 22400\,\mu\text{m} \times (0.75)^2 \times 5 \times 10^9 \approx 3.15\,\text{mW}

加上MUX的开关功耗(约2\sim3 mW),旁路网络总功耗约5\sim6 mW。虽然绝对值看似不大,但这仅是整数ALU的旁路网络——整个执行引擎(含浮点、SIMD、Load/Store)的旁路网络功耗可能达到15\sim25 mW,在总核心功耗1\sim2 W中占据显著比例。采用2-Cluster分簇后,总导线长度可减少40%\sim50%,功耗相应降低。

性能分析 2 — 分簇对旁路网络三重瓶颈的缓解效果

下表总结了8端口处理器采用2-Cluster(每Cluster 4端口)后对旁路网络三重瓶颈的缓解效果:

指标全连接(8端口)2-Cluster(4+4)改善
通路数562×12+8=322 \times 12 + 8 = 3243%-43\%
MUX扇入9:15:144%-44\%
MUX延迟\sim28 ps\sim20 ps29%-29\%
布线宽度\sim202 μ\mum\sim115 μ\mum43%-43\%
导线总功耗\sim3.2 mW\sim1.9 mW41%-41\%

2-Cluster方案中的32条通路包括:每个Cluster内部4×3=124 \times 3 = 12条(共24条),加上跨Cluster的2×4=82 \times 4 = 8条。跨Cluster的8条通路需要额外1个周期延迟,但由于有传输寄存器缓冲,它们不在MUX的关键路径上。

旁路网络跨越不同FU的延迟

即使在没有分簇的处理器中,不同功能单元(FU)之间的旁路延迟也不完全相同。这种延迟差异来自两个方面:物理距离功能单元类型

物理距离导致的延迟差异

在处理器的物理版图(floorplan)中,不同的执行单元位于不同的物理位置。两个相邻的ALU之间传递旁路数据可能只需要穿越数十微米的金属导线,而从浮点乘法单元到整数ALU之间的距离可能达到数百微米甚至更远。在先进工艺中,每100 μ\mum的长距离导线引入约10\sim15 ps的传播延迟(包含中继缓冲器的延迟)。当物理距离超过200\sim300 μ\mum时,旁路数据的传播延迟可能接近或超过一个时钟周期的一半。

功能单元类型导致的延迟差异

不同类型的功能单元有不同的流水线深度和结果产生时间:

  • 简单ALU(加法、逻辑、移位):1个周期产出结果,结果在当拍末尾即可通过旁路转发。

  • 复杂ALU(乘法):3\sim5个周期产出结果,旁路数据在最后一个流水级的末尾可用。

  • Load单元:2\sim3个周期(地址计算 + 缓存访问),结果在缓存命中后可用。

  • 浮点/SIMD单元:3\sim7个周期,且结果通常在独立的浮点寄存器文件中,与整数寄存器文件不共享旁路网络。

在没有分簇的设计中,所有这些不同延迟的旁路通路都被混合在同一个全连接网络中。调度器必须根据每个源操作数的具体来源(哪个FU、哪一级流水线)来判断数据何时可用——这使得调度逻辑变得极为复杂。

全连接旁路网络与分簇旁路网络的对比。左图:6个执行端口全连接,需要30条旁路通路,MUX扇入为7。右图:分成两个Cluster,每个Cluster内部仅需6条通路,MUX扇入降至4,但跨Cluster转发需额外1个周期。
全连接旁路网络与分簇旁路网络的对比。左图:6个执行端口全连接,需要30条旁路通路,MUX扇入为7。右图:分成两个Cluster,每个Cluster内部仅需6条通路,MUX扇入降至4,但跨Cluster转发需额外1个周期。

图 35.1直观对比了全连接旁路网络和分簇旁路网络的区别。在全连接情况下,6个执行端口之间需要6×5=306 \times 5 = 30条旁路通路,每个端口的操作数MUX需要从7个来源中选择(6条旁路 + 1个寄存器文件读端口)。而采用2-Cluster的组织后,每个Cluster内部只有3个执行端口,旁路通路减少到3×2=63 \times 2 = 6条,MUX扇入降至4——大幅减少了布线负担和MUX延迟。代价是跨Cluster的数据转发需要额外1个时钟周期。

分簇的核心权衡可以用一个简洁的等式概括:

性能损失=f(跨Cluster通信频率)×跨Cluster延迟惩罚 \text{性能损失} = f(\text{跨Cluster通信频率}) \times \text{跨Cluster延迟惩罚}

如果调度器能够将大多数相互依赖的指令分配到同一个Cluster中执行,则跨Cluster通信频率很低,分簇带来的性能损失就很小。反之,如果指令分配策略不佳,频繁的跨Cluster通信将严重侵蚀IPC。这就是后面几节将要深入讨论的Cluster感知调度策略的核心课题。

设计权衡 1 — 全连接 vs. 分簇旁路网络

全连接旁路网络的优势在于任意两个执行端口之间的旁路延迟都是1个周期(假设单周期ALU),不需要复杂的Cluster感知调度逻辑,编译器和微架构都更简单。其劣势在于布线复杂度为O(P2)O(P^2),当P>46P > 4\sim 6时物理实现困难,MUX延迟成为关键路径瓶颈。

分簇旁路网络的优势在于将旁路复杂度从O(P2)O(P^2)降至O(K(P/K)2)O(K \cdot (P/K)^2)(其中KK为Cluster数量),使得宽发射处理器的物理实现成为可能。其劣势在于跨Cluster通信引入额外延迟(通常1个周期),需要Cluster感知的调度策略,调度器复杂度增加。

实际设计中,大多数高性能处理器选择了某种形式的分簇。在4-wide及以下的设计(如ARM Cortex-A78)中,全连接旁路仍然可行;在6-wide及以上的设计(如Alpha 21264、Apple M系列)中,分簇几乎是唯一选择。

分簇复杂度的数学建模

为了在设计空间中快速评估不同分簇方案的效果,建立一个简单的数学模型是有帮助的。假设PP个FU被均匀划分到KK个Cluster中,每个Cluster包含p=P/Kp = P/K个FU。我们可以定义以下度量:

旁路通路数

全连接旁路的通路数为:

Nfull=P×(P1)N_{\text{full}} = P \times (P - 1)

分簇后,每个Cluster内部的通路数为p×(p1)p \times (p - 1)KK个Cluster共有K×p×(p1)K \times p \times (p-1)条组内通路。跨Cluster通路数取决于互联拓扑。最常见的是全连接Cluster互联(每对Cluster之间都有通路),此时跨Cluster通路数为K×(K1)×pK \times (K-1) \times p(每个Cluster的pp个FU结果都需要能到达其他K1K-1个Cluster)。总通路数为:

Ncluster=Kp(p1)+K(K1)p=Kp(p1+K1)=P(p+K2) N_{\text{cluster}} = K \cdot p(p-1) + K(K-1) \cdot p = K \cdot p \cdot (p - 1 + K - 1) = P \cdot (p + K - 2)

通路数的比值为:

NclusterNfull=p+K2P1\frac{N_{\text{cluster}}}{N_{\text{full}}} = \frac{p + K - 2}{P - 1}

对于P=8,K=2P = 8, K = 2p=4p = 4):Ncluster/Nfull=(4+22)/(81)=4/70.57N_{\text{cluster}}/N_{\text{full}} = (4 + 2 - 2)/(8 - 1) = 4/7 \approx 0.57,即通路数减少43%。对于P=8,K=4P = 8, K = 4p=2p = 2):比值为(2+42)/7=4/70.57(2 + 4 - 2)/7 = 4/7 \approx 0.57——有趣的是,当K×pK \times p固定为PP时,2-Cluster和4-Cluster的总通路数相同。但关键区别在于:4-Cluster方案中组内通路更少(每Cluster仅2×1=22 \times 1 = 2条),而跨Cluster通路更多(4×3×2=244 \times 3 \times 2 = 24条 vs. 2×1×4=82 \times 1 \times 4 = 8条),这对布线拓扑和延迟有完全不同的影响。

MUX扇入

每个FU的操作数MUX扇入在分簇方案下为:

F=p+(K1)p+1=Kp+1=P+1 F = p + (K-1) \cdot p + 1 = K \cdot p + 1 = P + 1

等一下——这似乎与全连接方案完全相同!如果每个FU需要能接收来自所有其他Cluster的旁路,MUX扇入并不减少。那分簇的MUX延迟改善从何而来?

关键在于时序不对称性:跨Cluster的旁路数据经过传输寄存器延迟了1个周期,因此它比组内旁路数据提前1个周期到达MUX。在MUX的物理实现中,这些提前到达的信号可以走较慢的通路(例如MUX的第一级选择),而组内旁路数据走关键的最后一级选择。这样,MUX的关键路径扇入实际上只有p+1p + 1(组内FU数加上寄存器文件),而非P+1P + 1

Fcritical=p+1=PK+1 F_{\text{critical}} = p + 1 = \frac{P}{K} + 1

对于P=8,K=2P = 8, K = 2Fcritical=5F_{\text{critical}} = 5,比全连接的9:1显著降低。这才是分簇真正改善MUX延迟的机制。

设计提示

分簇对MUX延迟的改善并非来自减少MUX的总输入数,而是来自将输入分成"关键路径输入"和"非关键路径输入"两类。组内旁路在关键路径上,跨Cluster旁路由于提前一拍锁存,不在关键路径上。这种通过时间偏移来减少关键路径深度的技术思想,在处理器设计的许多其他场景中也有应用——例如多级TLB查找、缓存的提前启动(early restart)等。

Cluster IQ

分簇不仅影响旁路网络的物理布线,还深刻影响发射队列(Issue Queue, IQ)的组织方式。在分簇处理器中,发射队列可以是集中式的(一个统一的IQ为所有Cluster服务),也可以是分布式的(每个Cluster拥有自己的专属IQ)。IQ的分簇策略与FU的分簇策略紧密耦合——指令在被分派到某个Cluster的IQ后,只能在该Cluster中的FU上执行。本节讨论两种主要的分簇维度:按功能单元类型分簇和按操作数类型分簇,以及指令到Cluster的分配策略。

按功能单元类型分簇

最直观的分簇方式是按照功能单元的类型来划分——将执行相同或相似操作的FU放在同一个Cluster中。这种分簇方式的合理性在于:不同类型的指令通常操作不同的数据类型(整数、浮点、地址),它们之间的直接数据依赖较少,因此跨Cluster通信的频率天然较低。

典型的功能类型分簇

现代处理器中常见的分簇包括:

  1. 整数ALU Cluster:包含简单ALU(加法、减法、逻辑运算、移位)和复杂ALU(乘法、除法)。整数ALU之间的依赖非常频繁——典型的整数代码中,连续的ALU指令之间存在大量RAW相关(例如地址计算链、循环归纳变量更新等),因此将所有整数ALU放在同一个Cluster(或少数几个Cluster)中是性能关键。

  2. Load/Store Cluster:包含地址生成单元(AGU)、Load单元和Store单元。Load/Store指令需要访问TLB和数据缓存,其物理实现(包括缓存SRAM阵列、TLB CAM等)占据较大的芯片面积,自然与其他FU有一定的物理距离。Load/Store Cluster通常拥有独立的IQ(称为Load/Store Queue或Address Queue)。

  3. 浮点/SIMD Cluster:包含浮点加法器、浮点乘法器、浮点除法/开方单元、SIMD整数和浮点运算单元。浮点/SIMD指令使用独立的物理寄存器文件(浮点PRF),与整数PRF不共享旁路网络,因此浮点/SIMD Cluster天然与整数Cluster隔离。

硬件描述 1 — 按功能类型分簇的物理布局

在物理版图上,按功能类型分簇的处理器通常呈现以下布局模式:

  • 整数执行单元位于芯片核心区域的一侧,紧邻整数寄存器文件和整数发射队列。

  • Load/Store单元位于L1数据缓存附近——因为Load/Store单元需要直接访问缓存SRAM阵列,将它们放在缓存旁边可以最小化地址和数据信号的传播距离。

  • 浮点/SIMD单元位于芯片核心的另一侧或底部,拥有独立的浮点寄存器文件和浮点发射队列。

  • 整数Cluster与Load/Store Cluster之间需要频繁交换数据(Load结果送入整数寄存器文件,Store需要整数寄存器的地址和数据),因此它们在物理上通常相邻。

  • 整数Cluster与浮点Cluster之间的数据交换较少(仅在整数-浮点移动指令和某些特殊指令中发生),因此可以有更大的物理距离。

按功能类型分簇的局限性

这种分簇方式的一个主要问题是整数Cluster内部仍然可能面临旁路网络过大的问题。当处理器拥有4个甚至更多整数ALU时,即使浮点和Load/Store已经独立分簇,整数ALU内部的全连接旁路网络仍然可能过于复杂。这就需要在整数ALU内部进一步分簇——这正是Alpha 21264和其他高性能处理器所采用的策略。

另一个问题是Load指令的结果通常需要被整数ALU使用(例如指针追踪模式:ld x1, 0(x2) \rightarrow add x3, x1, x4),这意味着Load/Store Cluster与整数ALU Cluster之间存在频繁的数据依赖。如果两个Cluster之间的通信延迟过大,指针追踪(pointer chasing)等延迟敏感的代码模式将受到严重影响。

混合分簇:功能类型与对称性的结合

在实际设计中,纯粹按功能类型分簇往往不够——整数Cluster内部可能还需要进一步细分。这就产生了混合分簇的设计:在第一层按功能类型分簇(整数 vs. 浮点 vs. Load/Store),在第二层按对称性分簇(将同类型的多个FU分成若干组)。这种两层分簇结构在现代处理器中非常普遍。

例如,一个拥有6个整数ALU的处理器可以采用以下混合分簇方案:

  • 第一层:整数Cluster、Load/Store Cluster、浮点/SIMD Cluster。

  • 第二层:整数Cluster内部分为两个子Cluster,每个子Cluster包含3个ALU。

  • 子Cluster内部全连接旁路(9条通路),子Cluster之间有限互联(6条通路,1周期额外延迟)。

这种层次化分簇的总旁路通路数为2×9+6=242 \times 9 + 6 = 24,远少于6-ALU全连接的6×5=306 \times 5 = 30条通路。更重要的是,24条通路中有18条是短距离的Cluster内部通路,只有6条是较长距离的跨Cluster通路——这对布线压力的缓解非常显著。

按操作数类型分簇

另一种分簇维度是按照操作数(即寄存器编号)来划分Cluster。这种方式不是按照"指令做什么"来分簇,而是按照"指令操作哪些寄存器"来分簇。其典型实现是将物理寄存器文件分成两半,每个Cluster拥有一半寄存器的完整拷贝(或一半寄存器的独占访问权)。

Alpha 21264的操作数分簇

Alpha 21264是按操作数类型分簇的经典案例。它的整数执行引擎包含两个完全对称的Cluster,每个Cluster拥有:

  • 1个整数ALU(2个Cluster共2个ALU)。

  • 1份完整的80个物理寄存器的副本。

关键设计决策在于寄存器文件的复制:Alpha 21264选择在每个Cluster中放置一份完整的寄存器文件副本,而非将寄存器分成两半。这意味着每条指令无论被分配到哪个Cluster,都能直接读取其源操作数——不存在"寄存器不在本Cluster中"的问题。

然而,寄存器文件的复制带来了写一致性问题:当一条指令在Cluster 0中产生结果并写入Cluster 0的寄存器文件副本时,这个结果也必须被同步写入Cluster 1的寄存器文件副本,以保持两份副本的一致性。这个同步写操作需要通过跨Cluster的写通路完成,额外消耗1个周期的延迟。

Alpha 21264风格的双Cluster整数执行引擎。每个Cluster拥有独立的IQ和完整的寄存器文件副本。Cluster内部旁路延迟为0周期(同拍转发),跨Cluster写回需额外1个周期。
Alpha 21264风格的双Cluster整数执行引擎。每个Cluster拥有独立的IQ和完整的寄存器文件副本。Cluster内部旁路延迟为0周期(同拍转发),跨Cluster写回需额外1个周期。

图 35.2展示了Alpha 21264风格的双Cluster结构。分派逻辑将指令分配到两个Cluster之一的IQ中。一旦指令进入某个Cluster的IQ,它将在该Cluster的ALU上执行,并首先写回该Cluster的本地寄存器文件副本。与此同时(或延迟1个周期),结果也被写入另一个Cluster的寄存器文件副本。

操作数分簇的优缺点

按操作数分簇的主要优势是:每个Cluster的结构完全对称,硬件设计复杂度较低(只需设计一个Cluster然后实例化两次)。其主要劣势在于寄存器文件的复制——每增加一个Cluster就需要多一份完整的寄存器文件副本,面积和功耗开销显著。对于拥有大量物理寄存器的现代处理器(例如256个以上的整数物理寄存器),复制完整的寄存器文件可能不再经济。

另一种操作数分簇的变体是寄存器分区(Register Partitioning)——不复制寄存器文件,而是将寄存器分成两半(例如偶数寄存器在Cluster 0,奇数寄存器在Cluster 1)。这种方式避免了寄存器文件的复制开销,但引入了一个新问题:如果指令的源操作数分布在不同的Cluster中(例如一个源来自偶数寄存器,另一个来自奇数寄存器),则必须进行跨Cluster读取,增加了延迟。

寄存器分区的量化分析

在寄存器分区方案中,一条双操作数指令需要跨Cluster读取的概率取决于其两个源寄存器是否落在不同的分区中。假设物理寄存器被均匀分成KK个分区(KK个Cluster各持有N/KN/K个寄存器,NN为总寄存器数),且指令的源操作数在所有物理寄存器上均匀分布,则两个源操作数落在不同分区的概率为:

Pcross=11K P_{\text{cross}} = 1 - \frac{1}{K}

对于K=2K = 2(双分区),Pcross=50%P_{\text{cross}} = 50\%——有一半的指令需要跨Cluster读取至少一个操作数。这个比例非常高,会导致严重的性能损失。相比之下,寄存器复制方案的跨Cluster通信比例通常只有20%\sim30%(取决于分派策略)。因此,寄存器分区在高性能处理器中很少被直接采用,除非与某种形式的操作数预取(operand prefetching)或本地缓存结合使用。

折衷方案:部分复制

介于完全复制和完全分区之间,有一种部分复制方案:每个Cluster拥有完整寄存器文件的读副本,但只有写入本Cluster产生的结果才需要同步到其他Cluster。读副本可以使用更小、更快的SRAM或寄存器堆实现(例如只保留最近写入的MM个寄存器的副本),当所需寄存器不在本地读副本中时,通过跨Cluster的读通路从远程Cluster的主寄存器文件中读取。这种设计类似于缓存的概念——本地读副本相当于一个小的寄存器缓存。

设计提示

寄存器文件复制与寄存器文件分区代表了两种截然不同的设计哲学。复制方式以面积换延迟——任何指令都可以在本地Cluster中读取所有源操作数,但面积翻倍;分区方式以延迟换面积——避免了面积开销,但部分指令需要跨Cluster读取操作数。在实践中,Alpha 21264选择了复制方式(因为当时物理寄存器数量较少,仅80个),而现代处理器由于物理寄存器数量更多,更倾向于采用其他形式的分簇。

集中式IQ与分布式IQ的选择

在分簇处理器中,发射队列的组织方式有两种极端选择:集中式IQ(一个统一的大IQ为所有Cluster的FU服务)和分布式IQ(每个Cluster拥有自己的专属IQ)。两者之间还存在各种混合方案。

集中式IQ

在集中式IQ方案中,所有待发射的指令都位于同一个IQ中,IQ的选择逻辑从中选出就绪的指令,并动态决定将每条指令发送到哪个Cluster的FU上。这种方案的优势在于:

  • 全局最优选择:选择逻辑能够看到所有就绪指令,可以做出全局最优的发射决策。

  • 天然负载均衡:不存在某个Cluster的IQ满而其他Cluster的IQ空的情况。

  • 分配灵活:指令在发射时才确定目标Cluster,而非在分派时就绑定,这提供了更多的调度灵活性。

然而,集中式IQ的劣势也很明显:

  • IQ面积和功耗:大型集中式IQ(例如96项以上)的CAM比较器和优先级选择逻辑的面积和功耗随项目数超线性增长。

  • 唤醒延迟:来自不同Cluster的FU完成标签都需要广播到同一个IQ,标签广播线较长,延迟较大。

  • 选择到执行的延迟:IQ选中指令后,需要将指令发送到目标Cluster的FU——如果IQ与FU不在同一物理位置,这段传输需要额外时间。

分布式IQ

在分布式IQ方案中,每个Cluster拥有一个较小的专属IQ。指令在分派阶段就被绑定到某个Cluster的IQ中,之后只能在该Cluster的FU上执行。Alpha 21264就采用了这种方案——每个整数Cluster有一个10项的IQ。

分布式IQ的优势在于:

  • 更小的IQ:每个IQ更小(例如10\sim16项 vs. 集中式的32\sim64项),CAM比较和选择逻辑更快。

  • 本地唤醒更快:本Cluster FU的完成标签只需广播到本地IQ,物理距离短,延迟小。

  • IQ与FU紧密耦合:IQ和FU在物理上相邻,选择到执行的路径极短。

分布式IQ的劣势在于:

  • 分派时绑定:指令一旦分派到某个Cluster,就无法改变。如果分派决策不佳,该Cluster的IQ可能满溢,而其他Cluster的IQ还有空闲。

  • 总IQ容量利用率低KK个各nn项的分布式IQ的有效容量小于1个K×nK \times n项的集中式IQ,因为负载不均衡时部分IQ条目被浪费。

  • 跨Cluster唤醒需要额外延迟:远程Cluster FU的完成标签需要穿越Cluster边界才能到达本地IQ。

混合方案

实际的高性能处理器往往采用混合方案。例如,Intel的某些处理器使用了分区式调度器(partitioned scheduler):物理上是多个小IQ,但逻辑上通过统一的分派和溢出机制协调,当某个分区满时可以将指令重定向到另一个分区。这种方案兼顾了分布式IQ的时序优势和集中式IQ的灵活性。

性能分析 3 — 集中式IQ与分布式IQ的IPC对比

对于一个4-wide发射、2-Cluster的处理器配置,使用SPEC CPU整数基准的模拟结果显示:

IQ组织总项数有效利用率IPC(归一化)选择延迟
集中式3295%1.00较长
分布式(2×\times16)3282%0.96较短
分布式(2×\times12)2485%0.94最短
混合式(2×\times16+溢出)3290%0.98中等

分布式IQ的IPC损失主要来自有效利用率的降低——当负载不均衡时,部分IQ条目被浪费。混合方案通过溢出机制回收了大部分浪费的容量。

指令到Cluster的分配策略

无论采用哪种分簇方式,都需要一个关键的微架构决策:每条指令应该被分配到哪个Cluster?这个决策在分派阶段(dispatch stage)做出,且一旦做出就不可更改——指令一旦进入某个Cluster的IQ,就只能在该Cluster中等待执行。分配策略的好坏直接影响了跨Cluster通信的频率,进而影响处理器的IPC。

轮转分配(Round-Robin)

最简单的分配策略是轮转:交替将指令分配到Cluster 0和Cluster 1。例如,程序顺序中的第1、3、5、\ldots条指令进入Cluster 0,第2、4、6、\ldots条指令进入Cluster 1。

轮转分配的优点是实现极为简单(只需一个1位计数器),且天然保证了两个Cluster之间的负载均衡。其缺点是完全不考虑指令间的依赖关系——如果两条相互依赖的指令恰好被分配到不同的Cluster,就会产生跨Cluster通信惩罚。对于典型的整数代码,连续指令之间的RAW相关概率约为30%\sim50%,这意味着轮转分配会导致大量的跨Cluster通信。

依赖感知分配(Dependence-Aware Dispatch)

更智能的策略是考虑指令间的依赖关系。核心思想是:将依赖于同一个Cluster中已有指令的新指令尽量分配到同一个Cluster。这样,依赖链中的指令可以通过Cluster内部的快速旁路传递数据,避免跨Cluster的额外延迟。

具体实现方式如下:当一条新指令到达分派阶段时,调度器检查其源操作数的生产者指令位于哪个Cluster:

  1. 如果所有源操作数的生产者都在同一个Cluster中,则将新指令分配到该Cluster。

  2. 如果源操作数的生产者分布在不同的Cluster中,则需要启发式决策——例如选择"最晚完成"的源操作数的生产者所在的Cluster,因为这个源操作数是关键路径上的操作数。

  3. 如果源操作数已经在寄存器文件中就绪(不需要旁路),则依赖关系不影响Cluster选择,可以按负载均衡原则分配。

性能分析 4 — 分配策略对IPC的影响

研究表明,对于典型的SPEC CPU整数基准,不同分配策略对双Cluster处理器IPC的影响如下(基于4-wide发射、2-Cluster配置,跨Cluster延迟1周期的模拟数据):

分配策略跨Cluster通信比例IPC(归一化)
轮转分配45%\sim55%0.85\sim0.90
随机分配48%\sim52%0.84\sim0.89
依赖感知分配20%\sim30%0.95\sim0.98
理想全连接(无分簇)0%1.00

依赖感知分配将跨Cluster通信比例从约50%降低到约25%,使得分簇处理器的IPC损失从10%\sim15%降低到仅2%\sim5%。这说明分配策略是分簇设计中最关键的微架构决策之一。

负载均衡约束

依赖感知分配虽然能减少跨Cluster通信,但可能导致严重的负载不均衡——如果一段代码中所有指令都属于同一条长依赖链,依赖感知策略会将它们全部塞入同一个Cluster,导致该Cluster的IQ溢出或执行端口饥饿,而另一个Cluster则空闲。

因此,实际的分配策略需要在依赖感知和负载均衡之间取得平衡。一种常见的实现是设置一个不均衡阈值:当两个Cluster的IQ占用率之差超过阈值时,强制将新指令分配到负载较轻的Cluster,即使这意味着跨Cluster通信。

Alpha 21264的分配策略

Alpha 21264采用了一种相对简单的分配方式:它不使用依赖感知策略,而是根据指令对中两条指令之间的关系来分配。Alpha 21264每周期分派2条整数指令(配对分派),分派逻辑检查这两条指令之间是否存在数据依赖:

  • 如果两条指令之间数据依赖:一条分配到Cluster 0,另一条分配到Cluster 1。

  • 如果两条指令之间数据依赖(后一条依赖前一条的结果):将两条指令分配到同一个Cluster,以利用Cluster内部的快速旁路。

这种策略简单但有效——它确保了最常见的"相邻指令依赖"情况能够在同一个Cluster内部解决。

多条指令的分配决策

当处理器每周期分派的指令数量超过2条时,分配决策变得更加复杂。考虑一个6-wide的处理器,每周期需要将6条指令分配到3个Cluster中。此时,分配决策需要同时考虑:

  1. 6条指令两两之间的依赖关系(最多(62)=15\binom{6}{2} = 15对)。

  2. 这些指令与已经在各Cluster IQ中等待的指令之间的依赖关系。

  3. 3个Cluster的当前负载状况。

精确求解这个优化问题的复杂度为O(KN)O(K^N)KK个Cluster、NN条指令),对于K=3,N=6K=3, N=6就是36=7293^6 = 729种组合——在半个时钟周期内做出最优决策几乎不可能。因此实际设计采用贪心启发式:按程序顺序逐条处理每条指令,根据其源操作数的生产者位置和当前Cluster负载快速做出分配决策。这种贪心策略虽然不能保证全局最优,但延迟极低,且在实践中的效果接近最优解(通常在95%以内)。

关键路径优先分配

贪心启发式中一个重要的改进是关键路径优先(critical-path-first)策略。其核心思想是:在决定指令的Cluster分配时,优先满足位于关键路径上的依赖关系。

具体来说,对于一条有两个源操作数的指令,如果两个源操作数的生产者在不同的Cluster中,则必须有一个操作数需要跨Cluster传输。关键路径优先策略选择将指令分配到关键路径源操作数的生产者所在的Cluster——也就是最晚产出结果的那个源操作数。这样,关键路径上的旁路转发在Cluster内完成(0额外周期),而非关键路径上的操作数承受跨Cluster的额外1周期延迟——由于它不在关键路径上,这个额外延迟不会增加总执行时间。

估计关键路径源操作数的方法有几种:

  • 最晚完成时间:选择估计完成时间最晚的源操作数作为关键路径源。这需要调度器维护每个未完成指令的估计完成时间,实现成本较高。

  • 指令类型启发:如果一个源来自多周期指令(如乘法、Load),另一个来自单周期指令(如ALU),则多周期指令的结果更可能在关键路径上。

  • 已就绪 vs. 未就绪:如果一个源已经就绪(在寄存器文件中),另一个未就绪(等待旁路),则未就绪的源更可能在关键路径上。

设计提示

分派阶段的Cluster分配决策位于处理器的关键路径上——它直接影响分派吞吐率,进而影响前端和后端的平衡。如果Cluster分配逻辑过于复杂导致分派阶段需要额外的流水级,那么增加的流水线深度可能抵消分簇带来的旁路网络改善。在实际设计中,Cluster分配逻辑通常需要在半个时钟周期内完成,这严格限制了分配策略的复杂度。Alpha 21264的简单配对分配策略之所以成功,很大程度上是因为它足够简单以满足时序约束。

Cluster Bypass

分簇旁路网络的核心设计挑战在于如何处理跨Cluster的数据转发。在Cluster内部,旁路网络的设计与传统的全连接旁路网络完全相同——只是规模更小、延迟更短。真正引入新问题的是跨Cluster通信:它需要将数据从一个Cluster的输出端口传输到另一个Cluster的输入端口,这段物理距离上的传播延迟加上必要的时序调整,通常需要额外1个或多个时钟周期。

组内旁路与跨组旁路

组内旁路(Intra-Cluster Bypass)

组内旁路是指同一个Cluster中不同FU之间的数据旁路转发。由于同一Cluster内的FU物理位置相近、共享相同的旁路网络,组内旁路可以在同一个时钟周期内完成。在典型的配置中,一条单周期ALU指令在第NN周期产生结果,通过组内旁路,依赖于该结果的另一条指令可以在第N+1N+1周期开始执行——这与没有分簇的处理器完全相同,不引入额外延迟。

组内旁路网络的设计遵循标准的全连接拓扑。假设一个Cluster内有pp个FU,则组内旁路需要p×(p1)p \times (p-1)条单向旁路通路(如果是带方向的),或p2p^2条(包括自身旁路)。在典型的2-Cluster设计中,p=23p = 2\sim 3,旁路通路数为494\sim 9——这对布线和MUX延迟的压力非常小。

跨组旁路(Inter-Cluster Bypass)

跨组旁路是指从一个Cluster的FU输出端到另一个Cluster的FU输入端的数据转发。由于两个Cluster在物理上的距离较远,且需要穿越Cluster边界的布线通道,跨组旁路通常需要额外1个周期的延迟。

在实现层面,跨组旁路通常涉及以下步骤:

  1. 在第NN周期,Cluster A中的FU产生计算结果。

  2. 结果被锁存到跨Cluster的传输寄存器(staging register)中。

  3. 在第N+1N+1周期,传输寄存器中的数据通过跨Cluster互联到达Cluster B。

  4. 在第N+1N+1周期末,数据被Cluster B的输入MUX采样,可用作Cluster B中指令的源操作数。

  5. 因此,依赖于Cluster A结果的Cluster B中的指令最早在第N+2N+2周期开始执行。

与组内旁路相比,跨组旁路多了1个周期的延迟——从"产生者到消费者"的总延迟从1周期变为2周期。

组内旁路 vs. 跨组旁路的时序比较。场景1中,I1和I2在同一Cluster中,I2在I1的下一周期即可开始执行。场景2中,I1在Cluster 0、I2在Cluster 1,I2需要多等1个周期才能获得I1的结果。
组内旁路 vs. 跨组旁路的时序比较。场景1中,I1和I2在同一Cluster中,I2在I1的下一周期即可开始执行。场景2中,I1在Cluster 0、I2在Cluster 1,I2需要多等1个周期才能获得I1的结果。

旁路MUX的修改

在分簇处理器中,每个FU的操作数选择MUX需要扩展以接纳跨Cluster的旁路数据。假设Cluster内有pp个FU,有KK个Cluster(每个Cluster结构相同),则操作数MUX的输入来源包括:

  • pp条组内旁路通路(来自本Cluster中pp个FU的当拍结果)。

  • (K1)×p(K-1) \times p条跨组旁路通路(来自其他K1K-1个Cluster中pp个FU的结果,延迟1周期)。

  • 1\sim2个寄存器文件读端口。

总MUX扇入为p+(K1)×p+1=Kp+1p + (K-1) \times p + 1 = K \cdot p + 1。在2-Cluster、每Cluster 2个FU的配置下,MUX扇入为2×2+1=52 \times 2 + 1 = 5,与全连接4-FU的情况(扇入5)相同。这似乎没有减少MUX扇入——但关键区别在于:组内旁路的物理导线很短(Cluster内部),而跨Cluster旁路虽然导线较长,但数量更少、布线更有规律性。此外,跨Cluster旁路数据到达MUX的时间比组内旁路早一个周期(因为它经过了传输寄存器的锁存),因此它可以在MUX的多个输入中走一条较慢的通路,不在关键路径上。

跨Cluster通信的延迟

跨Cluster通信的延迟是分簇设计中最关键的参数之一。它直接决定了分簇对性能的影响程度——1个周期的额外延迟在大多数情况下是可接受的,但2个或更多周期的额外延迟将严重降低IPC。

跨Cluster延迟的物理来源

跨Cluster延迟由以下几个部分组成:

  1. 导线传播延迟:数据从源Cluster的FU输出端到目标Cluster的MUX输入端的物理距离上的传播延迟。在典型的处理器版图中,两个相邻Cluster之间的距离约为200\sim500 μ\mum,对应的导线延迟约为20\sim80 ps。

  2. 驱动和接收延迟:发送端需要驱动器(driver)来驱动长导线,接收端需要接收器(receiver)来恢复信号质量。驱动器和接收器各引入约10\sim30 ps的延迟。

  3. 时钟域对齐:如果两个Cluster使用同一个时钟源但时钟到达时间(clock skew)不同,则数据传输需要额外的时序裕量来保证建立时间(setup time)。

  4. 传输寄存器的开销:跨Cluster数据通常需要在中途锁存一次(通过传输寄存器),以将长距离传输分成两段,每段适合一个时钟周期。

将以上延迟相加,典型的跨Cluster总延迟约为100\sim200 ps。在一个5 GHz处理器(周期200 ps)中,这恰好落在"刚好不能在1个周期内完成、但可以在2个周期内充裕完成"的范围——这就是为什么大多数分簇设计选择1个额外周期的跨Cluster延迟。

典型延迟配置

在最常见的分簇配置中:

  • 组内旁路延迟 = 0个额外周期(即单周期ALU操作后,下一周期消费者就可执行)。

  • 跨组旁路延迟 = 1个额外周期(即单周期ALU操作后,消费者需等到后2个周期才能执行)。

用数学表达:设指令IpI_p(生产者)在周期TT完成执行,指令IcI_c(消费者)依赖于IpI_p的结果。则IcI_c最早的执行开始周期为:

Texec(Ic)={T+1如果 Ip 和 Ic 在同一ClusterT+2如果 Ip 和 Ic 在不同Cluster T_{\text{exec}}(I_c) = \begin{cases} T + 1 & \text{如果 } I_p \text{ 和 } I_c \text{ 在同一Cluster} \\ T + 2 & \text{如果 } I_p \text{ 和 } I_c \text{ 在不同Cluster} \end{cases}

这1个周期的差异看似微小,但在延迟敏感的代码模式中影响巨大。例如,考虑一条由10个依赖ALU指令组成的关键路径:如果所有指令在同一Cluster中,关键路径长度为10个周期;如果每隔一条指令就发生一次跨Cluster通信,关键路径长度将变为10+5=1510 + 5 = 15个周期——增加了50%。

跨Cluster通信的性能影响量化

跨Cluster延迟对IPC的影响取决于多个因素的交互作用。本小节建立一个分析模型并用具体数值量化其影响。

依赖链长度与跨Cluster频率的交互

考虑一条长度为LL的依赖链(全部为单周期ALU指令),其中有比例rr的依赖需要跨Cluster传输。则关键路径的总长度为:

Tcrit=L+rL=L(1+r)T_{\text{crit}} = L + r \cdot L = L(1 + r)

IPC的损失近似为:

ΔIPCr1+r×IPCbase\Delta\mathrm{IPC}\approx \frac{r}{1 + r} \times \mathrm{IPC}_{\text{base}}

r=0.25r = 0.25(即25%的依赖跨Cluster)时,IPC损失约20%;当r=0.10r = 0.10时,IPC损失约9%。这说明,即使只有少量的跨Cluster通信,关键路径也会受到明显影响。将rr控制在10%以下是分簇设计的关键目标。

不同程序特征下的影响差异

跨Cluster延迟的影响因程序特征而异。整数代码通常具有较高的指令级依赖密度——典型的整数基准中,约60%\sim70%的指令至少有一个源操作数来自前3条指令以内的结果。这意味着整数代码对跨Cluster延迟最敏感。

浮点代码的依赖密度相对较低,且浮点指令的延迟较长(3\sim5周期),跨Cluster的额外1周期在总延迟中的占比更小。因此,浮点代码对分簇的容忍度更高。

性能分析 5 — 不同程序类型下跨Cluster延迟的影响

以下模拟数据展示了1周期跨Cluster额外延迟对不同类型程序IPC的影响(2-Cluster,依赖感知分配,跨Cluster通信比例约25%):

程序类型依赖密度IPC损失(1周期)IPC损失(2周期)
整数计算密集型3%\sim6%8%\sim14%
指针追踪型极高5%\sim10%12%\sim22%
浮点计算型1%\sim3%3%\sim7%
SIMD/向量型<<1%1%\sim3%

指针追踪型程序(如链表遍历、树搜索)对跨Cluster延迟最敏感,因为其关键路径由Load\toALU\toLoad的紧密依赖链构成。当跨Cluster延迟为2周期时,IPC损失可达22%——这解释了为什么几乎所有成功的分簇设计都将跨Cluster延迟控制在1周期。

跨Cluster延迟与指令类型的交互

跨Cluster延迟的实际影响还取决于指令的类型和流水线深度。对于单周期ALU指令,跨Cluster的1个额外周期将生产者到消费者的延迟从1周期增加到2周期——相对增加100%。但对于3周期的乘法指令,跨Cluster的额外1周期将延迟从3周期增加到4周期——相对只增加33%。对于Load指令(4\sim5周期),相对增加仅20%\sim25%。

这意味着:单周期ALU指令之间的依赖是跨Cluster延迟影响最大的场景。在整数代码中,单周期ALU指令占所有指令的50%\sim60%,且它们之间的依赖密度最高。这就解释了为什么整数ALU内部的分簇设计最为关键——整数ALU是跨Cluster延迟最敏感的指令类型。

多级Cluster的延迟

在某些超宽处理器中,可能存在多级Cluster层次——类似于缓存层次,最近的Cluster之间通信延迟最小,较远的Cluster之间延迟更大。例如,一个拥有4个Cluster的处理器可能采用如下延迟配置:

  • 同一Cluster内:0个额外周期。

  • 相邻Cluster之间:1个额外周期。

  • 距离最远的两个Cluster之间:2个额外周期。

这种多级延迟配置进一步增加了调度器的复杂度,但可以支持更多数量的Cluster,从而使更宽的发射成为可能。

硬件描述 2 — 跨Cluster传输寄存器的实现

跨Cluster传输寄存器(staging register)是实现跨Cluster旁路的关键硬件结构。其设计需要考虑以下因素:

  1. 宽度:传输寄存器的宽度等于数据通路宽度(通常为64位)加上标签宽度(6\sim8位,用于标识目标物理寄存器)和有效位(1位)。总宽度约为73\sim75位。

  2. 深度:每条跨Cluster旁路通路需要至少1个传输寄存器。如果每个周期最多有pp条结果需要跨Cluster传输(pp是每个Cluster的FU数量),则需要pp个传输寄存器。

  3. 时钟域:传输寄存器的输入在源Cluster的时钟域上采样,输出在目标Cluster的时钟域上驱动。如果两个Cluster使用同一个时钟树但存在时钟偏斜(clock skew),传输寄存器还需要额外的时序裕量。

  4. 功耗管理:传输寄存器在每个周期都需要被时钟驱动,即使没有数据需要传输。使用门控时钟(clock gating)可以在无数据时关闭传输寄存器的时钟以节省功耗。

Cluster感知的调度策略

在分簇处理器中,指令调度面临的核心挑战是:不仅要考虑"何时发射"(时间维度),还要考虑"在哪里发射"(空间维度)。Cluster感知调度(Cluster-Aware Scheduling)是指在指令分派和调度过程中显式考虑Cluster位置信息,以最小化跨Cluster通信的策略。

分派阶段的Cluster感知

最直接的Cluster感知调度发生在分派阶段——当指令从重命名阶段进入发射队列时,分派逻辑需要决定将指令分配到哪个Cluster。我们在35.2.4 节中已经讨论了依赖感知分配策略的基本原理。这里进一步讨论其实现细节。

分派逻辑需要维护一个生产者位置表(Producer Location Table),记录每个物理寄存器的最新生产者位于哪个Cluster。当新指令到达分派阶段时,分派逻辑查询其源操作数对应的物理寄存器在生产者位置表中的条目,确定生产者的Cluster位置,然后据此做出分配决策。

Cluster感知分派逻辑示例。新指令的两个源操作数分别来自Cluster 0和Cluster 1(票数相同),结合IQ负载均衡信息,决策逻辑选择负载较轻的Cluster 1。
Cluster感知分派逻辑示例。新指令的两个源操作数分别来自Cluster 0和Cluster 1(票数相同),结合IQ负载均衡信息,决策逻辑选择负载较轻的Cluster 1。

生产者位置表的实现细节

生产者位置表(PLT)是一个以物理寄存器编号为索引的小型表,每个条目仅需log2K\lceil \log_2 K \rceil位(KK为Cluster数量)。对于2-Cluster设计,每个条目只需1位。假设处理器有NN个物理寄存器,PLT的总面积为N×log2KN \times \lceil \log_2 K \rceil位。对于N=256,K=2N = 256, K = 2,PLT仅需256位(32字节)——这是一个非常小的结构,可以用简单的寄存器堆实现。

PLT的更新发生在分派阶段:当一条指令被分配到Cluster kk时,其目标物理寄存器对应的PLT条目被更新为kk。PLT的读取也发生在分派阶段:新指令的每个源操作数查询PLT以确定其生产者的Cluster位置。

需要注意的是,PLT只记录了"最新生产者的Cluster位置",但并不保证该生产者的结果尚未写回寄存器文件。如果结果已经写回寄存器文件,则无论生产者在哪个Cluster,消费者都可以直接从寄存器文件读取,跨Cluster延迟不再相关。因此,PLT的信息是保守的——它可能导致不必要的"跟随生产者"决策,但不会导致功能错误。

调度器内部的Cluster感知

除了分派阶段的Cluster选择外,调度器在唤醒逻辑中也需要感知跨Cluster延迟。具体来说,当Cluster A中的指令产生结果时,同一个Cluster中等待该结果的指令可以在下一周期被唤醒并选中;而另一个Cluster中等待该结果的指令需要在再下一周期才能被唤醒。

这意味着唤醒逻辑需要区分"本地唤醒"和"远程唤醒":

  • 本地唤醒:标签广播到达本Cluster的IQ,本周期比较匹配,下周期指令可被选中发射。

  • 远程唤醒:标签广播首先到达本Cluster的IQ进行比较匹配,同时也被发送到远程Cluster,但远程Cluster的IQ在下一周期才收到标签并进行比较匹配,因此远程Cluster中被唤醒的指令要多等1个周期才能被选中。

在硬件实现上,远程唤醒可以通过在跨Cluster的标签广播路径上插入一级流水线寄存器来实现——标签被锁存一拍后再广播到远程Cluster的比较器。

硬件描述 3 — Cluster感知唤醒逻辑的实现

在双Cluster处理器中,唤醒逻辑的实现需要以下修改(相比非分簇设计):

  1. 每个Cluster的IQ中,操作数就绪位的设置逻辑需要区分两种标签广播来源:

    • 本地广播总线:来自同一Cluster中FU的完成标签,当拍比较、当拍设置就绪位。

    • 远程广播总线:来自另一个Cluster中FU的完成标签,经过1拍延迟后到达本Cluster的比较器。

  2. 选择逻辑在选中指令时,不仅检查"所有操作数就绪",还需要确认就绪操作数的来源:如果某个操作数是通过远程唤醒变为就绪的,该指令的最早发射时间需要额外推迟1周期(以等待跨Cluster旁路数据到达)。

  3. 为避免由于远程唤醒的额外延迟导致的投机发射错误,有些处理器采用保守唤醒策略——只在数据确实可以通过旁路获得时才设置就绪位,而非提前投机唤醒。

Cluster分配逻辑的RTL示例

以下SystemVerilog代码展示了一个简化的依赖感知Cluster分配逻辑的核心部分,适用于2-Cluster配置:

verilog
module cluster_assign (
  input  logic [5:0] src1_preg,    // 源操作数1的物理寄存器号
  input  logic [5:0] src2_preg,    // 源操作数2的物理寄存器号
  input  logic       src1_ready,   // 源操作数1已在RF中就绪
  input  logic       src2_ready,   // 源操作数2已在RF中就绪
  input  logic [63:0] plt,         // 生产者位置表 (1bit per preg)
  input  logic [4:0]  iq0_count,   // Cluster 0 IQ占用计数
  input  logic [4:0]  iq1_count,   // Cluster 1 IQ占用计数
  output logic        target_cl    // 0=Cluster0, 1=Cluster1
);
  logic src1_cl, src2_cl;
  logic [1:0] vote;  // 对两个Cluster的投票

  // 查询生产者位置表
  assign src1_cl = plt[src1_preg];
  assign src2_cl = plt[src2_preg];

  // 依赖感知投票
  always_comb begin
    vote = 2'b00;
    if (!src1_ready) // 只有未就绪的源才计入投票
      vote = vote + (src1_cl ? 2'b10 : 2'b01);
    if (!src2_ready)
      vote = vote + (src2_cl ? 2'b10 : 2'b01);
  end

  // 决策: 依赖感知 + 负载均衡
  always_comb begin
    if (vote[1] > vote[0])
      target_cl = 1'b1;           // Cluster 1票数多
    else if (vote[0] > vote[1])
      target_cl = 1'b0;           // Cluster 0票数多
    else  // 票数相同, 按负载均衡
      target_cl = (iq0_count > iq1_count);
  end
endmodule

这段代码实现了35.2.4 节中描述的依赖感知分配策略的核心逻辑。plt(Producer Location Table)是一个64位寄存器,每位对应一个物理寄存器,记录其最新生产者所在的Cluster(0或1)。对于每个未就绪的源操作数,逻辑向其生产者所在的Cluster"投票",最终选择票数多的Cluster;如果票数相同,则按IQ占用率选择负载较轻的Cluster。

需要注意的是,实际的分配逻辑比上述代码复杂得多——它需要同时处理多条指令的分配(且分配决策之间有依赖),并需要处理各种边界情况(如两个源来自同一生产者、目标物理寄存器的PLT更新等)。但核心的"查询PLT + 投票 + 负载均衡"逻辑框架在所有分簇处理器中是通用的。

编译器层面的Cluster感知

除了微架构层面的调度策略外,编译器也可以参与Cluster感知调度。Cluster感知的指令调度(Cluster-Aware Instruction Scheduling)是编译器后端的一种优化技术,它在代码生成阶段对指令进行重排序,使得相互依赖的指令在程序顺序中相邻出现——这增加了它们被分派到同一Cluster的概率(尤其是在使用轮转或基于程序顺序的分派策略时)。

编译器还可以对寄存器分配(register allocation)进行Cluster感知优化:尽量将属于同一依赖链的值分配到相同的逻辑寄存器"区域"中,从而在按操作数分簇的处理器上减少跨Cluster访问。

不过,编译器层面的Cluster感知优化在实践中存在局限性:编译器通常不了解处理器的Cluster拓扑细节(Cluster数量、跨Cluster延迟等),且不同处理器的Cluster组织方式差异很大,针对特定处理器优化的代码可能在其他处理器上反而表现更差。因此,大多数高性能处理器主要依赖硬件层面的Cluster感知调度。

投机跨Cluster唤醒与取消

在某些激进的分簇设计中,调度器可能采用投机跨Cluster唤醒(speculative cross-cluster wakeup)策略。具体来说,当一条Load指令被发射到Load/Store Cluster时,调度器可以投机性地假设该Load将在2个周期后命中L1缓存,并提前向其他Cluster中依赖该Load结果的指令发送唤醒信号。如果Load确实命中缓存,则一切正常——依赖指令恰好在数据通过跨Cluster旁路到达时开始执行。但如果Load未命中缓存(L1 miss),则已经被投机唤醒的指令将读到无效数据,必须被取消(cancel/replay)。

投机唤醒与取消的机制增加了调度器的复杂度,但对于减少Load-to-use延迟在跨Cluster场景下的影响非常有效。这种机制在第 28.0 章中讨论的投机调度与重放(speculative scheduling and replay)的框架内自然适用,只是在分簇处理器中需要将重放范围扩展到跨Cluster的指令。

Cluster感知调度的IPC影响量化

为了更直观地理解Cluster感知调度的重要性,考虑以下代码序列在双Cluster处理器上的执行:

asm
add  x1, x2, x3    # I1: 被分配到 Cluster 0
    sub  x4, x1, x5    # I2: 依赖I1(x1), 应分配到 Cluster 0
    mul  x6, x7, x8    # I3: 无依赖, 分配到 Cluster 1
    xor  x9, x4, x6    # I4: 依赖I2(x4,CL0)和I3(x6,CL1)
    add  x10, x9, x11  # I5: 依赖I4(x9)

在这个例子中,指令I4的两个源操作数分别来自两个不同的Cluster(x4来自Cluster 0,x6来自Cluster 1)。无论I4被分配到哪个Cluster,都会有一个操作数需要跨Cluster传输。Cluster感知调度器需要选择将I4分配到持有其关键路径源操作数的Cluster——在这个例子中,I3是一条3周期乘法指令,其结果比I2的结果更晚可用,因此I4应该被分配到Cluster 1(与I3同侧),以避免在关键路径上增加额外延迟。

Cluster感知调度的效果:将依赖链中的指令保持在同一Cluster内可以显著缩短关键路径。左图中轮转分配导致3次跨Cluster传输(各+1周期),总延迟7周期;右图中Cluster感知分配将所有依赖指令放在Cluster 0,总延迟仅4周期。
Cluster感知调度的效果:将依赖链中的指令保持在同一Cluster内可以显著缩短关键路径。左图中轮转分配导致3次跨Cluster传输(各+1周期),总延迟7周期;右图中Cluster感知分配将所有依赖指令放在Cluster 0,总延迟仅4周期。

真实世界的Cluster设计

理论上的分簇策略需要在真实处理器中经受面积、功耗、时序和IPC的多维考验。本节通过三个具有代表性的案例——Alpha 21264、AMD Zen系列、Apple M系列——来展示不同时代、不同设计团队如何在分簇设计空间中做出具体选择。

Alpha 21264的Cluster

DEC(后被Compaq收购,再被HP收购)的Alpha 21264是处理器设计史上最具影响力的微架构之一,也是第一个在学术文献和工业界广泛讨论分簇设计的处理器。它于1998年推出,采用0.35 μ\mum工艺,主频500 MHz\sim667 MHz,是当时最快的微处理器之一。

案例研究 1 — Alpha 21264的整数执行引擎

Alpha 21264的整数执行引擎采用了经典的双Cluster设计,其核心参数如下:

  • 发射宽度:4-wide(2条整数 + 2条浮点/访存)。

  • 整数Cluster:2个完全对称的Cluster,每个Cluster包含1个整数ALU。

  • 寄存器文件:每个Cluster拥有一份完整的80项整数物理寄存器文件副本(共2份副本)。每份寄存器文件有2个读端口和2个写端口。

  • 发射队列:每个Cluster拥有独立的10项整数发射队列(共20项)。

  • 旁路网络

    • 组内旁路延迟:0个额外周期(当拍转发)。

    • 跨Cluster旁路延迟:1个额外周期。

Alpha 21264的分派策略

Alpha 21264每周期从重命名阶段接收最多4条指令(2条整数、2条浮点/访存)。对于2条整数指令,分派逻辑采用以下策略:

  1. 检查两条整数指令之间是否存在数据依赖。

  2. 如果无依赖:一条分配到Cluster 0,另一条分配到Cluster 1(交替分配,保证负载均衡)。

  3. 如果有依赖:两条指令分配到同一个Cluster,以利用组内旁路。Cluster的选择基于负载均衡——选择当前IQ占用率较低的Cluster。

这种策略的巧妙之处在于它只检查"当前这对指令之间的依赖",而不追溯更早指令的位置。这使得分派逻辑非常简单——只需要一个比较器检查第二条指令的源寄存器是否匹配第一条指令的目标寄存器。

80项PRF副本的同步机制

Alpha 21264的双Cluster设计中,最具特色的是寄存器文件的完全复制。两份80项寄存器文件副本必须保持一致。具体的同步机制如下:

  1. 当Cluster XX中的指令产生结果时,结果同时驱动到两个目的地:

    • Cluster XX的本地寄存器文件的写端口——在当拍完成写入。

    • 跨Cluster的传输通路——数据通过传输寄存器到达Cluster YY

  2. Cluster YY的寄存器文件在下一拍完成写入(从传输寄存器接收数据)。

  3. 每个Cluster的寄存器文件因此需要额外的写端口来接收远程数据。在Alpha 21264中,每个寄存器文件有2个本地写端口(来自本Cluster的ALU和Load/Store单元)和1\sim2个远程写端口(来自另一个Cluster的结果)。

这种同步机制的代价是:

  • 写端口增加:每个寄存器文件需要额外的写端口,增加了面积和功耗。80项×\times4个端口(2读+2写)的寄存器文件在0.35 μ\mum工艺下已经是相当大的结构。

  • 写带宽竞争:当两个Cluster同时产生结果时,每个Cluster的寄存器文件需要同时执行1次本地写和1次远程写——共2次写操作。如果写端口不足,可能需要序列化(stall)。

  • 一致性窗口:在结果写入本地寄存器文件但尚未写入远程寄存器文件的1个周期窗口内,两份副本不一致。如果恰好在这个窗口内,远程Cluster中的指令需要读取该寄存器,它将读到旧值。Alpha 21264通过旁路网络解决了这个问题——如果远程Cluster中的指令需要刚刚产生的结果,它通过跨Cluster旁路获得数据(延迟1周期),而不是从本地寄存器文件读取(此时可能还是旧值)。

硬件描述 4 — Alpha 21264寄存器文件副本的读写时序

考虑以下时序场景:Cluster 0中的指令I1在周期TT产生结果写入物理寄存器P42。

周期Cluster 0的RF[P42]Cluster 1的RF[P42]
TT写入新值旧值(尚未更新)
T+1T+1新值(可读)写入新值(从传输寄存器)
T+2T+2新值(可读)新值(可读)

在周期T+1T+1,如果Cluster 1中的指令需要P42的值,有两种获取方式:(a) 通过跨Cluster旁路直接获得(延迟1周期,此时恰好可用);(b) 等到周期T+2T+2从本地寄存器文件读取。设计中选择(a)——旁路优先,避免额外等待。

Alpha 21264的性能评估

Alpha 21264的双Cluster设计被广泛认为是非常成功的。在SPEC CPU 95/2000基准测试中,与理想的全连接旁路设计相比,双Cluster设计的IPC损失约为3%\sim5%——这得益于其简单有效的分派策略和仅1周期的跨Cluster延迟。

更重要的是,双Cluster设计使得Alpha 21264能够实现0.35 μ\mum工艺下500\sim667 MHz的主频——这在1998年是破纪录的。如果采用全连接旁路网络,旁路MUX的额外延迟可能迫使时钟频率降低10%\sim15%。因此,虽然分簇导致了3%\sim5%的IPC损失,但更高的时钟频率带来了10%\sim15%的频率增益——净效果是性能提升5%\sim10%。这是分簇设计的经典成功案例:以少量IPC换取显著频率提升,总性能反而更高。

Alpha 21264的历史影响

Alpha 21264的分簇设计深刻影响了后来的处理器架构。其核心设计师之一Dirk Meyer后来领导了AMD K8/K10的设计,将分簇理念引入了x86处理器。Joel Emer等人后来加入Intel,推动了Intel处理器中分簇技术的发展。Alpha 21264的双Cluster设计也成为了处理器架构教科书中的经典案例。

性能分析 6 — Alpha 21264的IPC-频率权衡

Alpha 21264的设计展示了分簇的"IPC-频率权衡"原理:

方案IPC频率性能(IPC×\times频率)相对性能
全连接(假设)1.00575 MHz5751.00
双Cluster(实际)0.96667 MHz6401.11

双Cluster方案虽然IPC损失4%,但频率提升16%,最终性能提升11%。这说明分簇不仅仅是"不得已的折衷"——在频率受限的设计中,分簇实际上可以提升总性能。

AMD Zen系列的执行单元组织

AMD的Zen微架构家族(从2017年的Zen 1到2024年的Zen 5)代表了x86处理器在执行单元组织上的持续演进。虽然AMD并不使用"Cluster"这个术语来描述其执行单元组织,但其设计在本质上体现了分簇思想——不同类型的执行端口被组织成相对独立的组,组内有快速旁路,组间需要额外的转发延迟。

Zen 4的执行端口组织

AMD Zen 4(2022年,5 nm工艺,用于Ryzen 7000系列)的整数执行引擎包含以下执行端口:

  • 4个ALU端口:ALU0、ALU1、ALU2、ALU3。每个ALU端口可以执行加法、减法、逻辑运算和移位。其中,ALU0和ALU1还可以执行分支指令的条件判断;ALU2和ALU3还可以执行乘法运算。

  • 3个AGU端口:AGU0、AGU1、AGU2。AGU(Address Generation Unit,地址生成单元)计算Load/Store指令的内存地址。其中,AGU0和AGU1既可以产生Load地址也可以产生Store地址,AGU2只用于Store地址。

  • Load/Store端口:与AGU配合工作。AGU计算出地址后,Load/Store管线执行缓存访问。

AMD Zen 4的整数执行引擎组织。4个ALU端口和3个AGU端口构成两个逻辑组,ALU之间有快速旁路网络,Load结果到ALU的旁路需要额外延迟。
AMD Zen 4的整数执行引擎组织。4个ALU端口和3个AGU端口构成两个逻辑组,ALU之间有快速旁路网络,Load结果到ALU的旁路需要额外延迟。

Zen 4的旁路组织

Zen 4的旁路网络体现了按功能类型分簇的特征:

  • ALU\toALU旁路:4个ALU之间有全连接(或接近全连接)的旁路网络,单周期ALU指令的结果可以在下一周期被任何其他ALU使用。这是因为4个ALU在物理上紧密相邻,旁路导线较短。

  • Load\toALU旁路:Load指令的结果从L1缓存读出后,需要通过较长的物理距离才能到达ALU端口。在Zen 4中,Load-to-use延迟为4个周期(地址计算1周期 + 缓存访问2周期 + 旁路/寄存器文件读取1周期),其中部分延迟来自Load单元与ALU之间的物理距离。

  • ALU\toAGU旁路:当ALU的结果被用作Load/Store的基地址时(例如add x1, x2, x3后跟ld x4, 0(x1)),ALU结果需要从ALU端口转发到AGU端口。Zen 4在这条通路上可能引入了1个周期的额外延迟。

Zen 4的调度器分区

Zen 4的整数调度器总容量为96项,分成4个24项的调度器分区(scheduler partition)。每个分区可以向特定的执行端口发射指令。这种分区式调度器在本质上就是分布式IQ的一种实现——每个分区服务于特定的执行端口子集,指令在分派时就被绑定到某个分区。

分区之间的指令不能互相迁移,但分派逻辑会根据各分区的占用率来平衡新指令的分配。这种设计兼顾了分布式IQ的时序优势(每个分区只有24项,唤醒和选择逻辑更快)和集中式IQ的灵活性(通过分派时的动态分配实现负载均衡)。

Zen 5的进一步扩展

AMD Zen 5(2024年)将整数执行能力进一步扩展:

  • 6个ALU端口(从Zen 4的4个增加到6个)。

  • 3个AGU端口(与Zen 4相同)。

  • 整数发射宽度从6-wide扩展到8-wide。

Zen 5在6个ALU端口之间维持全连接旁路网络的难度显著增加。据公开的微架构分析,Zen 5可能在6个ALU端口之间采用了某种形式的分组——例如将6个ALU分成两组(每组3个),组内全连接旁路,组间有额外延迟。这种设计选择正是分簇理论在现代处理器中的典型应用。

Zen 5的旁路非对称性证据

微基准测试揭示了Zen 5执行端口之间旁路延迟的非对称性。考虑以下测试模式:一条ALU指令在端口XX执行,紧接着的依赖指令被强制调度到端口YY。通过遍历所有(X,Y)(X, Y)的组合并测量依赖链的执行延迟,可以推断出不同端口对之间的旁路延迟。

初步分析表明,Zen 5的6个ALU端口可能被组织为两个"旁路域"(bypass domain):

  • 域A:ALU0、ALU1、ALU2——这三个端口之间的旁路延迟一致,为1周期。

  • 域B:ALU3、ALU4、ALU5——同样,三个端口之间旁路延迟为1周期。

  • 跨域旁路:从域A到域B或反向,旁路延迟可能为2周期(即额外1周期)。

如果这一推断成立,则Zen 5的整数ALU组织本质上就是一个2-Cluster设计(每Cluster 3个ALU),与Alpha 21264的设计理念一脉相承——只是规模从每Cluster 1个ALU增长到了每Cluster 3个ALU,反映了25年间工艺进步和设计技术的积累。

案例研究 2 — 从Zen 1到Zen 5的执行端口演进

AMD Zen微架构家族的执行端口数量稳步增长,每一代都面临着旁路网络复杂度增加的挑战:

微架构年份ALU端口AGU端口工艺节点
Zen 120174214 nm
Zen 22019437 nm
Zen 32020437 nm
Zen 42022435 nm
Zen 52024634 nm

从Zen 1到Zen 4,ALU端口数量保持在4个,旁路网络复杂度在可控范围内。Zen 5将ALU端口增加到6个,这是一个重大跨越——6×\times6的旁路网络比4×\times4复杂了36/16=2.2536/16 = 2.25倍。结合4 nm先进工艺的更紧凑布局,Zen 5的执行引擎设计团队无疑面临了巨大的旁路网络物理实现挑战,分簇技术在其中扮演了关键角色。

Apple M系列的执行端口布局

Apple的M系列处理器(从2020年的M1到2024年的M4)搭载的高性能核心(Firestorm、Avalanche、Everest等)代表了当前超宽发射处理器设计的极致。以M1的Firestorm核心为例,其整数执行能力达到了前所未有的水平——拥有6个整数ALU端口和4个Load/Store端口,整数发射宽度达到8-wide。

Firestorm核心的执行端口

根据公开的逆向工程和性能分析,Apple M1 Firestorm核心的执行引擎包含以下端口:

  • 6个整数ALU端口:其中至少2个支持复杂操作(乘法、除法),其他4个执行简单ALU操作。

  • 4个Load/Store端口:2个Load端口 + 2个Store端口(或4个可配置的Load/Store端口)。

  • 4个浮点/SIMD端口:2个FMUL/FADD端口 + 2个其他SIMD操作端口。

  • 2个分支端口

  • 总计约16\sim18个执行端口,发射宽度约8-wide。

这种超宽的执行引擎如果采用全连接旁路网络,仅整数ALU的旁路就需要6×5=306 \times 5 = 30条通路——这与Alpha 21264时代6-wide的全连接方案面临相同的挑战,但Apple需要在现代5 nm工艺的极紧凑面积预算下实现它。

Firestorm的分簇策略

关于Firestorm核心的内部分簇细节,Apple没有公开披露。但基于以下间接证据,我们可以推断其执行引擎采用了某种形式的分簇:

  1. 延迟分析:在某些微基准测试中,连续相互依赖的ALU指令序列的延迟取决于它们被分配到哪些执行端口。如果所有指令恰好在同一组端口上执行,延迟最短;如果分散在不同端口组上,延迟略长。这暗示了不同端口组之间存在不同的旁路延迟。

  2. 发射队列的组织:Firestorm核心的发射队列据分析是分布式的——整数IQ和浮点/SIMD IQ是分开的,且整数IQ可能进一步分成多个子队列。分布式IQ天然与分簇执行引擎配合。

  3. 物理布局约束:在5 nm工艺下,6个ALU的全连接旁路网络的导线长度和MUX延迟使得单周期全连接几乎不可能实现。分簇是唯一合理的选择。

Firestorm的旁路延迟逆向分析

通过精心设计的微基准测试,研究者发现Firestorm的6个整数ALU端口并非完全对称。具体表现为:

  • 大多数ALU端口对之间的back-to-back延迟为1周期(标准的单周期ALU旁路)。

  • 某些特定端口对之间的back-to-back延迟偏尔为2周期,暗示这些端口不在同一个旁路域内。

  • 从Load端口到ALU端口的延迟一致为4周期(Load-to-use latency),说明所有ALU端口到L1缓存的距离相近,或者Apple使用了统一的Load结果分发网络。

这些观察结果与"6个ALU分成2组、每组3个"的假设一致——与前面对Zen 5的推断类似。这可能反映了一个普遍的工程结论:3个ALU是单个旁路域在现代高频处理器中能够承载的上限。超过3个ALU就需要分簇。

案例研究 3 — Apple M系列的执行引擎演进

Apple M系列的高性能核心展示了移动处理器向超宽发射方向的激进推进:

核心芯片年份整数ALULd/St工艺
FirestormM12020645 nm
AvalancheM22022645 nm
EverestM32023643 nm
M42024643 nm

从M1到M4,Apple保持了6个整数ALU + 4个Load/Store的超宽配置,而非继续增加端口数量。这一决策可能反映了工程团队对旁路网络复杂度的判断——6个ALU已经达到了在合理的面积和功耗预算下可实现的上限。在同一期间,Apple的重点从增加执行宽度转向优化缓存层次、提高频率和改善能效比。

Firestorm核心的设计表明,在分簇技术的帮助下,即使是移动处理器也可以实现媲美甚至超越桌面处理器的执行宽度。M1在发布时的单线程整数性能可以与当时的Intel Core i9-11900K竞争,这在很大程度上归功于其超宽执行引擎——而这个超宽引擎的物理实现离不开精心的分簇设计。

分簇与能效比

Apple M系列的一个突出特点是其极高的能效比(Performance per Watt)。分簇设计在能效方面也有贡献:通过将旁路网络分割成较小的局部网络,每个Cluster的旁路MUX更小、驱动的导线更短,动态功耗显著降低。在Apple的设计中,分簇不仅是为了解决物理实现问题,也是功耗优化策略的一部分。

Apple M系列的大小核分簇差异

Apple M系列处理器同时包含高性能核心(P-core,如Firestorm)和高效率核心(E-core,如Icestorm)。两种核心在分簇策略上有显著差异:

  • P-core:6个整数ALU,需要分簇。超宽发射优先单线程IPC最大化,分派策略侧重于减少跨Cluster延迟。

  • E-core:仅2\sim3个整数ALU,全连接旁路完全可行,不需要分簇。简单的执行引擎优先能效比。

这种大小核架构的一个有趣效应是:同一段代码在P-core和E-core上的微架构行为完全不同。在P-core上,指令调度受到Cluster边界的约束;在E-core上则没有这种约束。操作系统的调度器需要理解这种差异,将对延迟敏感的任务(如指针追踪密集的数据库查询)分配到P-core上的合适线程上下文中。

性能分析 7 — Apple M系列P-core与E-core的执行引擎对比

以下数据展示了Apple M2芯片中P-core(Avalanche)与E-core(Blizzard)的执行引擎关键参数对比:

参数P-core (Avalanche)E-core (Blizzard)
整数ALU数量63
Load/Store端口42
发射宽度8-wide4-wide
需要ALU分簇是(推测为2-Cluster)
整数IQ总容量\sim160项\sim48项
ALU-to-ALU旁路部分跨Cluster需+1c全连接,1c
核心面积\sim4.0 mm2^2\sim0.7 mm2^2
单线程IPC
能效比中高最高

P-core的面积是E-core的5.7倍,但单线程IPC的提升远不到5.7倍——超宽发射的收益递减效应在此清晰可见。分簇是使P-core的超宽引擎在面积和时序约束下成为可能的关键技术。

Intel处理器中的分簇实践

Intel在其高性能x86处理器中也广泛采用了分簇技术,但实现方式与Alpha 21264或AMD Zen有所不同。

Sunny Cove/Golden Cove的执行引擎

Intel的Golden Cove微架构(用于12代Core,2021年)是一个典型的例子。它拥有:

  • 5个ALU端口(从Ice Lake的4个增加到5个)。

  • 2个Load端口 + 2个Store数据端口 + 2个Store地址端口。

  • 发射宽度为6-wide。

Intel的设计文档暗示,Golden Cove的整数执行引擎采用了分区式调度器(partitioned scheduler),不同的调度器分区服务于不同的执行端口子集。这种设计在功能上等价于分簇——每个调度器分区就是一个"逻辑Cluster"。

Intel的统一调度器与分区

Intel处理器的一个有趣特点是其调度器的组织方式。从Skylake开始,Intel采用了统一调度器(Unified Reservation Station)——一个大的集中式调度器同时服务于整数和浮点指令。但统一调度器在物理上是分区的——不同分区的条目可以向不同的执行端口发射。

这种"逻辑统一、物理分区"的设计本质上是一种隐式分簇。指令在分派时被分配到特定的调度器分区(基于目标执行端口的类型),之后只能在该分区关联的执行端口上执行。不同分区之间的唤醒信号需要跨越分区边界传播,可能引入额外的延迟——这与显式分簇的跨Cluster唤醒延迟在原理上完全相同。

Lion Cove的进一步演化

Intel的Lion Cove微架构(用于Lunar Lake,2024年)在Golden Cove的基础上进一步扩展了执行能力。据公开分析,Lion Cove可能将整数ALU端口增加到6个,与AMD Zen 5和Apple M系列的设计水平相当。这意味着Intel也将面临6-ALU旁路网络的物理实现挑战,需要某种形式的分簇。

值得注意的是,Intel的处理器架构在分簇方面可能比AMD和Apple更加保守。Intel传统上更注重时钟频率(Intel处理器的频率通常高于同代AMD和Apple产品),而分簇的主要收益之一就是提高时钟频率。如果Intel已经通过其他工程手段(如深流水线、激进的物理设计优化)实现了高频率,那么分簇带来的额外频率收益可能相对较小——此时分簇的主要动机就纯粹是布线可行性。

三大厂商分簇策略的比较

综合Alpha/DEC、AMD、Apple和Intel的设计实践,可以总结出几种不同的分簇策略风格:

案例研究 4 — 三大厂商的分簇策略风格

  1. DEC/Alpha风格(显式对称分簇):将同类FU均匀分成对称的Cluster,每个Cluster拥有完整的寄存器文件副本。优点是概念清晰、设计规整;缺点是寄存器文件面积翻倍。代表:Alpha 21264。

  2. AMD风格(分区调度器 + 功能非对称):不显式定义Cluster边界,而是通过分区调度器将指令引导到特定的执行端口。不同端口的功能覆盖不完全相同(如ALU0/1支持分支,ALU2/3支持乘法),形成隐式的非对称分簇。优点是灵活性高、可以渐进式扩展;缺点是优化空间不如显式分簇大。代表:AMD Zen 4/5。

  3. Apple风格(超宽+隐式分簇):激进地增加执行端口数量(6个ALU + 4个Ld/St),通过精心的物理设计实现端口分组,对外不暴露Cluster细节。优点是最大化了单线程IPC;缺点是设计复杂度极高,且功耗较大。代表:Apple M1\simM4 P-core。

这三种风格反映了不同的设计优先级:Alpha优先设计简洁性,AMD优先可扩展性,Apple优先性能极限。没有哪种风格绝对优于其他——最佳选择取决于具体的产品需求、设计团队的专长和目标市场。

设计提示

Intel、AMD和Apple的设计实践表明:无论是否使用"Cluster"这个术语,所有拥有6个以上执行端口的高性能处理器都在某种程度上采用了分簇。差别仅在于分簇的粒度(2个、3个还是更多Cluster)、分簇的维度(按功能类型还是按对称性)、以及分簇对程序员和编译器的可见性(完全透明还是部分可见)。分簇已经成为超标量处理器设计中与流水线化、乱序执行同样基本的技术。

Cluster数量的设计权衡

Cluster数量是分簇设计中最关键的架构级决策之一。它决定了每个Cluster内的FU数量、旁路网络的规模、跨Cluster通信的拓扑复杂度,以及调度器的设计难度。本节系统分析2-Cluster、4-Cluster和非对称Cluster等不同配置的权衡。

2-Cluster配置

2-Cluster是最常见也最成功的分簇配置。Alpha 21264采用了2-Cluster,现代的Apple M系列和AMD Zen 5可能也采用了某种形式的2-Cluster。

2-Cluster的优势

  • 跨Cluster拓扑最简单:只有1对Cluster间通信,不存在"选择发送到哪个远程Cluster"的问题。所有跨Cluster数据只有一个目的地。

  • 调度器复杂度低:分派决策是二选一(Cluster 0 or 1),复杂度为O(2N)O(2^N)中取贪心近似,比3-Cluster或4-Cluster简单得多。

  • 跨Cluster延迟统一:所有跨Cluster通信的延迟相同(1个额外周期),调度器不需要区分"近Cluster"和"远Cluster"。

  • 负载均衡直观:两个Cluster之间的均衡可以用简单的计数器监控,当差距过大时强制切换。

2-Cluster的适用范围

2-Cluster适用于4\sim8个同类FU的处理器。当FU数量为4时(如Alpha 21264的2+2),每个Cluster有2个FU,组内旁路通路仅2×1=22 \times 1 = 2条。当FU数量为6时(如可能的Zen 5组织),每个Cluster有3个FU,组内旁路通路3×2=63 \times 2 = 6条——仍然非常可控。

但当FU数量达到8\sim10时,每个Cluster中有4\sim5个FU,组内旁路通路达到122012\sim 20条——Cluster内部的旁路网络本身开始面临与全连接方案类似的问题。此时需要考虑增加Cluster数量或采用层次化分簇。

2-Cluster的设计空间探索

即使确定采用2-Cluster配置,仍然有多个设计参数需要确定:

  1. 对称 vs. 非对称:两个Cluster应该包含相同数量的FU(对称),还是一个Cluster多一些FU(非对称)?对称设计简化了分派逻辑和负载均衡,非对称设计可以更好地匹配指令类型的分布。

  2. IQ的大小:每个Cluster的IQ应该多大?IQ过小会导致频繁的阻塞(stall),IQ过大则增加唤醒和选择逻辑的延迟。经验法则是:每个Cluster的IQ容量约为该Cluster FU数量的4\sim6倍。

  3. 寄存器文件组织:完全复制、分区还是层次化?选择取决于物理寄存器的总数和面积预算。

  4. 跨Cluster通路的带宽:每个周期最多允许几条结果跨Cluster传输?带宽不足会导致跨Cluster旁路的排队延迟,带宽过多则浪费布线资源。

性能分析 8 — 2-Cluster设计空间探索

以下模拟数据探索了2-Cluster配置下不同设计参数对6-ALU处理器IPC的影响:

配置分配IQ跨CL带宽IPC(归一化)
3+3对称依赖感知2×\times163/cyc0.963
3+3对称依赖感知2×\times123/cyc0.955
3+3对称依赖感知2×\times162/cyc0.958
3+3对称轮转2×\times163/cyc0.891
4+2非对称依赖感知16+83/cyc0.948

3+3对称配置搭配依赖感知分配和2×\times16 IQ是最优选择,IPC损失仅3.7%。将IQ从16项缩减到12项只额外损失0.8% IPC,是面积受限时的合理折衷。跨Cluster带宽从3/周期降到2/周期损失0.5% IPC——说明大多数时候不会同时有3条结果需要跨Cluster传输。

4-Cluster与多Cluster配置

当FU数量超过8个、或者设计者希望进一步缩小每个Cluster的内部旁路网络时,4-Cluster甚至更多Cluster的配置就进入了考虑范围。

4-Cluster的跨Cluster拓扑

4个Cluster之间的通信关系有(42)=6\binom{4}{2} = 6对,远多于2-Cluster的1对。跨Cluster互联的拓扑选择包括:

  1. 全连接:每对Cluster之间都有直接通路,跨Cluster延迟统一为1个额外周期。通路总数为6×2=126 \times 2 = 12条双向通路。布线资源需求较大,但延迟可预测。

  2. 环形连接:4个Cluster排成一个环,每个Cluster只与相邻的2个Cluster直接相连。相邻Cluster间延迟1个额外周期,对角Cluster间延迟2个额外周期。布线资源减半,但延迟不均匀。

  3. 交叉条(Crossbar):通过一个中央交换结构连接所有Cluster。延迟可以统一为1个额外周期(如果交叉条足够快),但交换结构本身占据较大面积。

4-Cluster的调度器复杂度

4-Cluster配置下,分派逻辑需要从4个Cluster中选择目标。对于一条有2个源操作数的指令,每个源可能来自4个Cluster之一,共有4×4=164 \times 4 = 16种源操作数位置组合。分派逻辑需要为每种组合确定最优的目标Cluster——这比2-Cluster(仅2×2=42 \times 2 = 4种组合)复杂4倍。

更严重的是,如果4个Cluster之间的延迟不均匀(如环形连接),调度器还需要考虑"选择哪个Cluster可以最小化关键路径上的跨Cluster延迟"。这是一个多目标优化问题(最小化跨Cluster延迟 + 最大化负载均衡),在半个时钟周期内求解非常困难。

性能分析 9 — 不同Cluster数量的IPC比较

以下模拟数据比较了8个ALU、不同Cluster数量配置下的性能(依赖感知分配,SPEC CPU整数基准平均值):

配置CL数每CL的FUMUX关键扇入跨CL比例IPC频率潜力
全连接1890%1.00
2-Cluster24522%0.96
4-Cluster42338%0.90最高
8-Cluster81255%0.82最高

2-Cluster是IPC-频率权衡的最优甜蜜点:IPC损失仅4%,但MUX关键扇入从9降到5,频率潜力显著提升。4-Cluster虽然MUX关键扇入更小,但跨Cluster通信比例升到38%,IPC损失达到10%——除非频率提升能弥补这个差距,否则4-Cluster不一定优于2-Cluster。8-Cluster的IPC损失过大(18%),在超标量处理器中基本不可行。

非对称Cluster配置

前面讨论的都是对称分簇——每个Cluster包含相同数量和类型的FU。在实际设计中,还存在一种重要的变体:非对称Cluster(Asymmetric Clustering),其中不同的Cluster拥有不同类型或不同数量的FU。

非对称Cluster的动机

非对称分簇的主要动机是:并非所有FU都被同等频繁地使用。例如:

  • 整数乘法指令在典型代码中的比例仅约3%\sim5%,因此只需1\sim2个乘法单元。

  • 整数除法更加稀有(<1%<1\%),通常只需1个除法单元。

  • 简单ALU指令(加法、逻辑、移位)占整数指令的50%\sim60%,需要更多的ALU。

  • 分支指令约占15%\sim20%,需要1\sim2个分支执行单元。

如果将乘法器、除法器与简单ALU均匀分布到所有Cluster中,每个Cluster可能只有0.5个乘法器(即2个Cluster共享1个)——这在硬件上很难实现。更自然的方式是将乘法器集中放在一个Cluster中。

典型的非对称配置

一种常见的非对称配置是:

  • Cluster A:3个简单ALU + 1个分支单元。处理大部分整数ALU和分支指令。

  • Cluster B:2个简单ALU + 1个乘法器 + 1个除法器。处理简单ALU指令和复杂整数运算。

在这种配置中,Cluster A有4个FU,Cluster B也有4个FU,但功能组合不同。分派逻辑需要确保乘法和除法指令始终被分配到Cluster B。对于简单ALU指令,两个Cluster都可以执行,分派逻辑可以基于依赖关系和负载均衡来选择。

非对称Cluster的调度挑战

非对称Cluster增加了调度的复杂度,因为分派逻辑不仅需要考虑"哪个Cluster",还需要考虑"该指令能否在目标Cluster上执行"。如果一条乘法指令因为依赖关系想去Cluster A,但Cluster A没有乘法器——此时必须将它分配到Cluster B,并承受跨Cluster的额外延迟。

这种"功能约束"与"依赖约束"之间的冲突在非对称Cluster中非常常见,处理方式有两种:

  1. 功能优先:始终将指令分配到能执行它的Cluster,牺牲依赖亲和性。

  2. 冗余执行能力:在每个Cluster中都放置一定的基础FU(如简单ALU),使得大多数常见指令都可以在任意Cluster上执行,只有少数特殊指令受功能约束。

现代处理器普遍采用第2种策略——这也是AMD Zen 4中ALU0/ALU1支持分支而ALU2/ALU3支持乘法的设计原因:通过让不同ALU"兼职"不同的特殊功能,在保持旁路网络统一性的同时提供了非对称的功能覆盖。

非对称Cluster的量化分析

为了理解非对称Cluster的效果,考虑一个6-ALU处理器需要分成2个Cluster的场景。假设指令类型分布如下:简单ALU 60%,分支15%,乘法5%,Load/Store 20%。

性能分析 10 — 对称 vs. 非对称Cluster配置的比较

以下模拟数据对比了两种配置(假设分支单元和乘法单元都与ALU共享端口):

配置Cluster ACluster BCL负载均衡IPC
对称3+33ALU(1BR,1MUL)3ALU(1BR,1MUL)0.963
非对称4+24ALU(2BR)2ALU(2MUL)0.948
非对称3+3功能差异3ALU(2BR)3ALU(2MUL)0.961

对称3+3配置的IPC最高,因为负载均衡最好。4+2非对称配置由于Cluster B只有2个ALU,在ALU密集的代码段中成为瓶颈。功能差异型3+3配置(两个Cluster的ALU数量相同但功能覆盖不同)几乎与纯对称配置相当——这说明保持FU数量的对称性比保持功能覆盖的对称性更重要。

Cluster间的指令迁移

在某些高级的非对称Cluster设计中,当指令在某个Cluster的IQ中等待时间过长(例如因为功能约束导致该指令只能在特定Cluster执行,但该Cluster已拥塞),可以将指令迁移(migrate)到另一个Cluster。指令迁移需要将指令从源Cluster的IQ中移除,并在目标Cluster的IQ中重新插入——这个过程至少消耗2\sim3个周期,但可以避免更长时间的等待。

指令迁移在硬件上实现较为复杂,且使用频率很低(通常不到1%的指令需要迁移),因此大多数处理器不实现此功能。但在极端负载不均衡的场景下,指令迁移可以作为一个"安全阀"防止性能严重退化。

一种更轻量级的替代方案是重分派(re-dispatch):当某个Cluster的IQ持续满载且另一个Cluster有空闲时,分派逻辑暂时忽略依赖感知策略,强制将新指令分配到空闲Cluster——虽然这会增加跨Cluster通信,但至少避免了因IQ满而导致的前端阻塞。这种"紧急泄洪"机制在大多数分簇处理器中都有实现,通常通过前述的不均衡阈值触发。

设计权衡 2 — Cluster数量的选择

Cluster数量的选择需要平衡多个维度:

较少的Cluster(例如2个)意味着每个Cluster内FU数量较多,Cluster内部旁路网络仍然较大,但跨Cluster的通信情况相对简单(只有2个Cluster之间的通信)。Alpha 21264的双Cluster设计就属于这一类。

较多的Cluster(例如4个或更多)意味着每个Cluster内FU数量很少(甚至每个Cluster只有1个FU),Cluster内部旁路极为简单,但跨Cluster通信的拓扑变得复杂——4个Cluster之间有6对通信关系,调度器需要考虑的Cluster位置组合也更多。此外,多Cluster可能导致某些指令的关键路径需要穿越多个Cluster边界,累积的跨Cluster延迟会很大。

在实践中,2\sim3个Cluster是最常见的选择。2-Cluster设计简单有效,适用于4\sim6个FU的处理器;3-Cluster设计可以支持6\sim9个FU,但调度器复杂度显著增加。超过3个Cluster的设计在传统超标量处理器中较为罕见,但在VLIW处理器和DSP中较为常见。

非对称Cluster提供了一个额外的设计维度——通过让不同Cluster专精于不同类型的指令,可以在不增加Cluster数量的情况下容纳更多种类的FU。但非对称设计增加了调度复杂度,且可能导致某些Cluster的利用率不均衡。

一个有用的经验法则是:KK个Cluster的设计中,跨Cluster通信比例大约为11/K1 - 1/K乘以依赖密度(假设随机分配),通过依赖感知分配可以将此比例降低到(11/K)×0.40.6(1 - 1/K) \times 0.4 \sim 0.6。对于K=2K = 2,这意味着跨Cluster通信比例约为0.5×0.5=25%0.5 \times 0.5 = 25\%;对于K=4K = 4,约为0.75×0.5=37.5%0.75 \times 0.5 = 37.5\%。当此比例超过30%时,IPC损失开始变得显著(>>5%),这限制了Cluster数量的上限。

Cluster与Load/Store单元的交互

Load/Store单元与整数ALU Cluster之间的交互是分簇设计中最关键的跨Cluster通信场景之一。本节详细分析这一交互及其对性能的影响。

Load结果到ALU的旁路路径

Load指令的结果是整数ALU最主要的数据来源之一。在典型的整数代码中,约25%\sim35%的指令是Load指令,而Load的结果约有70%\sim80%会被后续的ALU指令作为源操作数使用。因此,Load\toALU的旁路路径是处理器中最关键的数据转发路径。

在分簇处理器中,如果Load/Store单元和整数ALU位于不同的Cluster中(功能类型分簇),则Load结果到ALU的旁路需要跨越Cluster边界,引入额外的延迟。这对Load-to-use延迟(即从Load发射到其结果被消费者ALU指令使用的总周期数)有直接影响:

  • 无分簇:Load-to-use = L1命中延迟 = 4周期(典型值)。

  • Load/Store与ALU分簇:Load-to-use = L1命中延迟 + 跨Cluster延迟 = 4 + 1 = 5周期。

  • Load/Store与ALU同Cluster:Load-to-use = L1命中延迟 = 4周期(与无分簇相同)。

多出的1周期对指针追踪(pointer chasing)代码模式的影响尤为严重。在指针追踪中,每次Load的地址依赖于前一次Load的结果:ld x1, 0(x0) \to ld x2, 0(x1) \to ld x3, 0(x2) \to \cdots。如果Load-to-use从4周期增加到5周期,整个指针追踪链的延迟增加25%——这在链表遍历、哈希表查找等数据结构操作中是不可接受的。

解决方案:Load与ALU共置

大多数现代处理器选择将Load单元和至少部分ALU物理上紧邻放置,使得Load结果到ALU的旁路路径不需要跨越Cluster边界。具体实现方式包括:

  1. Load单元归入整数Cluster:将Load/Store单元与整数ALU放在同一个Cluster中,而非作为独立的Cluster。这是最直接的方式,但增加了每个整数Cluster的FU数量,可能导致Cluster内部旁路网络过大。

  2. 专用快速旁路通路:在Load/Store Cluster和整数Cluster之间建立一条特殊的快速旁路通路,使得Load结果到ALU的旁路不经过通常的传输寄存器,而是通过专用的低延迟导线直接到达ALU的输入MUX。这条快速通路的延迟被设计为0个额外周期(即与组内旁路相同),但其物理实现需要精心的版图优化。

  3. Load结果广播:Load结果通过一条独立的广播总线同时发送到所有整数Cluster,每个Cluster的MUX都有一个专用输入接收Load结果。这种方式确保了Load结果在所有Cluster中的可用时间相同。

设计提示

在分簇处理器的物理版图设计中,Load单元到ALU的旁路路径应该被赋予最高的优先级。即使其他跨Cluster通信可以容忍1个周期的额外延迟,Load-to-use延迟也应该被最小化。一种常见的物理设计策略是将Load单元放置在两个整数Cluster之间——这样它到两个Cluster的距离都较短,Load结果可以同时快速到达两个Cluster。

Store数据和Store地址的分簇考虑

Store指令需要两个输入:存储地址(由AGU计算)和存储数据(来自整数寄存器)。在分簇处理器中,这两个输入可能来自不同的Cluster,增加了Store执行的复杂性。

地址与数据的分离

大多数现代处理器将Store操作分成两个独立的微操作:

  • Store地址(STA):计算存储地址,写入Store Buffer的地址域。

  • Store数据(STD):将待存储的数据写入Store Buffer的数据域。

STA和STD可以独立执行,不需要同时完成。在分簇处理器中,STA通常在AGU端口执行(Load/Store Cluster),STD则可以在任意能读取整数寄存器的Cluster中执行。当Store数据的来源在远程Cluster中时,STD需要等待跨Cluster旁路——但由于STD不在关键路径上(Store操作是"退休时才可见"的),额外的1周期延迟通常不影响性能。

这是分簇设计中一个有趣的不对称性:Load路径对跨Cluster延迟极为敏感,而Store路径对延迟的容忍度较高。理解这种不对称性对于优化分簇的物理布局至关重要。

地址生成与整数ALU的依赖关系

Load/Store指令的地址通常由ALU指令计算。常见的模式包括:

  • 基址+偏移ld x1, 16(x2)——基址x2由之前的ALU指令产生。

  • 索引寻址:基址由一系列ALU指令(加法、移位)动态计算得出。

  • 循环归纳变量addi x2, x2, 8 \to ld x1, 0(x2)——每次循环迭代中,ALU更新基址后紧跟Load。

在分簇处理器中,如果计算基址的ALU指令和使用该基址的Load/Store指令不在同一个Cluster中,基址传递需要跨Cluster旁路,引入1周期额外延迟。这意味着Load指令的有效延迟(从基址可用到Load结果可用)增加了1周期。

对于循环归纳变量模式,这个额外延迟尤为严重:循环的每次迭代都包含一个ALU\toLoad的依赖,如果这个依赖每次都跨Cluster,每次迭代的延迟都增加1周期。对于一个紧循环(例如数组遍历),循环体的执行时间可能增加20%\sim30%。

asm
# 数组求和循环
    li   x3, 0          # sum = 0
    li   x4, 1000       # count
.loop:
    ld   x5, 0(x2)      # Load: 使用基址x2
    add  x3, x3, x5     # sum += array[i]
    addi x2, x2, 8      # 基址更新: x2 += 8
    addi x4, x4, -1     # count--
    bnez x4, .loop       # 循环

在上述代码中,addi x2, x2, 8(ALU操作)和ld x5, 0(x2)(Load操作)之间的依赖位于循环的关键路径上。如果addi在整数ALU Cluster中执行而ld在Load/Store Cluster中执行,每次循环迭代都会增加1周期的跨Cluster延迟。Cluster感知分派策略应该将addi x2, x2, 8分配到与Load单元物理相邻的Cluster中,或者确保Load单元和至少一个ALU共享快速旁路通路。

设计提示

在设计分簇处理器的AGU/Load通路时,至少应该保证一个整数ALU与AGU/Load单元之间有0额外延迟的快速旁路。这个ALU被称为地址ALU(Address ALU),它物理上紧邻AGU放置,专门用于执行地址计算指令。分派逻辑应该将地址计算指令(如addi产生的基址更新)优先分配到包含地址ALU的Cluster中。这种设计在AMD Zen系列中有明确体现——AGU端口与特定的ALU端口之间有专用的快速旁路通路。

Cluster与寄存器文件的交互

分簇设计对寄存器文件的组织方式有深远的影响。本节详细讨论在分簇处理器中寄存器文件的三种主要组织方式及其权衡。

完全复制的寄存器文件

完全复制是Alpha 21264所采用的方式:每个Cluster拥有一份完整的寄存器文件副本,所有Cluster中的副本保持一致。

面积开销

设处理器有NN个物理寄存器、KK个Cluster,每个寄存器宽WW位。一份完整的寄存器文件副本的面积近似为:

ARFN×W×(R+Wport)2A_{\text{RF}} \propto N \times W \times (R + W_{\text{port}})^2

其中RR是读端口数,WportW_{\text{port}}是写端口数。端口数的平方项来自于SRAM单元中位线和字线的交叉布线。KK份副本的总面积为K×ARFK \times A_{\text{RF}}

但需要注意的是,每份副本的端口数可以比不分簇时更少。在不分簇的设计中,一个寄存器文件需要2P2P个读端口和PP个写端口(PP个FU,每个2读1写)。分簇后,每个Cluster的寄存器文件只需2p2p个读端口和p+(K1)×p=K×pp + (K-1) \times p = K \times p个写端口(pp个本地写端口加上(K1)×p(K-1) \times p个远程写端口)。由于写端口数为K×p=PK \times p = P(与不分簇相同),但读端口数从2P2P降至2p2p,寄存器文件每份副本的面积实际上更小。当KK不大时(如K=2K = 2),总面积可能只增加30%\sim50%,而非翻倍。

写端口仲裁

在完全复制方案中,每个Cluster的寄存器文件需要接收来自所有KK个Cluster的写入。当多个Cluster同时产生结果时,写端口可能不足以在一个周期内完成所有写入。解决方案包括:

  • 增加写端口:为每个远程Cluster提供独立的写端口。这增加了面积但消除了冲突。

  • 写缓冲:使用小型写缓冲(write buffer)暂存无法立即写入的远程写操作,在后续周期写入。这可能增加一致性延迟。

  • 限制同时写入:通过调度约束,确保每个周期最多只有一定数量的远程写操作。这限制了并行度但简化了硬件。

完全复制的面积-端口权衡

完全复制方案中一个常被忽视的优势是:每份寄存器文件副本的端口数可以更少。在不分簇的PP端口处理器中,统一的寄存器文件需要2P2P个读端口和PP个写端口。SRAM的面积与端口数的平方成正比,因此一个(2P+P)(2P + P)-端口的寄存器文件面积约为(3P)2=9P2\propto (3P)^2 = 9P^2

在2-Cluster配置下,每个Cluster有p=P/2p = P/2个FU,本地寄存器文件需要2p2p个读端口和pp个本地写端口加pp个远程写端口(共2p2p个写端口)。总端口数为2p+2p=4p=2P2p + 2p = 4p = 2P。面积约为(2P)2=4P2\propto (2P)^2 = 4P^2。两份副本的总面积为2×4P2=8P22 \times 4P^2 = 8P^2,实际上比不分簇的9P29P^2更小

这个反直觉的结论——完全复制寄存器文件的总面积可能比不复制更小——是因为多端口SRAM的面积随端口数超线性增长。分簇将一个大的多端口结构拆成两个小的少端口结构,即使复制了一份,总面积也可能减少。

性能分析 11 — 寄存器文件面积的端口效应

以下数据对比了不同配置下寄存器文件的面积(归一化值,基于SRAM面积与端口数平方成正比的模型,128个物理寄存器×\times64位):

配置副本数读端口/副本写端口/副本每副本面积总面积
不分簇(8 FU)1168576\propto 576576
2-CL(4+4 FU)288256\propto 256512
4-CL(2+2+2+2)448144\propto 144576

2-Cluster配置下完全复制寄存器文件的总面积(512)实际上比不分簇(576)减少了11%。4-Cluster配置下总面积回到与不分簇相当,因为每个副本虽然读端口少,但写端口没有减少(需要接收来自3个远程Cluster的写入)。这说明2-Cluster是寄存器文件面积的"甜蜜点"。

分区的寄存器文件

分区方案将寄存器文件分成KK个不重叠的子集,每个Cluster只持有自己分区内的寄存器。这避免了面积翻倍的问题,但当指令的源操作数不在本Cluster的分区内时,需要跨Cluster读取。

分区策略

最简单的分区方式是按物理寄存器编号的奇偶或高低位划分:偶数寄存器在Cluster 0,奇数在Cluster 1。这种确定性分区(deterministic partitioning)的优点是查找简单——只需检查寄存器编号的最低位。缺点是跨Cluster读取的概率完全取决于编译器的寄存器分配结果,微架构无法控制。

更智能的分区方式是按写入者分区(writer-based partitioning):每个寄存器属于最后写入它的Cluster。这等价于让重命名逻辑在分配物理寄存器时,优先选择目标Cluster分区内的空闲寄存器。这种方式可以显著降低跨Cluster读取的概率(因为刚写入的值最可能被同一Cluster中的后续指令读取),但增加了重命名逻辑的复杂度。

跨分区读取的处理

当指令需要读取不在本Cluster分区内的寄存器时,有两种处理方式:

  1. 跨Cluster读请求:指令发出跨Cluster读请求,远程Cluster读取本地寄存器文件并通过跨Cluster数据通路返回数据。这至少需要1个额外周期。

  2. 读缓存(Read Cache):每个Cluster维护一个小型的读缓存,存储最近从远程Cluster读取的寄存器值。如果缓存命中,可以避免跨Cluster读请求。

设计提示

分区寄存器文件方案虽然节省了面积,但增加了微架构的复杂度——重命名逻辑、分派逻辑和读端口管理都需要感知分区信息。在物理寄存器数量较少时(如Alpha 21264的80个),完全复制的面积开销可以接受;在物理寄存器数量较多时(如现代处理器的256\sim384个),分区方案的面积优势变得更加重要。然而,分区方案的IPC损失也更大——对于需要最大化单线程性能的高性能核心,完全复制仍然是更好的选择。

层次化寄存器文件

第三种方案是层次化寄存器文件——结合了复制和分区的优点。其核心思想是:

  • 每个Cluster拥有一个小型的快速寄存器文件(L1 RF),存储最近写入的寄存器值。L1 RF的读取延迟为0周期(与FU的旁路时序匹配)。

  • 所有Cluster共享一个大型的慢速寄存器文件(L2 RF),存储所有物理寄存器的值。L2 RF的读取延迟为1\sim2周期。

  • 当指令的源操作数在本Cluster的L1 RF中命中时,直接本地读取(0额外延迟);未命中时,从L2 RF读取(1\sim2周期额外延迟)。

这种层次化组织类似于缓存层次——L1 RF是"寄存器缓存",L2 RF是"寄存器后备存储"。其优势在于:

  • L1 RF很小(例如16\sim32项),读写端口少、面积小、访问速度快。

  • L2 RF虽然大(存储所有物理寄存器),但由于L1 RF的过滤作用,L2 RF的访问频率较低,可以使用更慢但更密集的SRAM。

  • 不需要完整的跨Cluster数据复制——每个Cluster只需在L1 RF中保留最近的"工作集"。

层次化寄存器文件的挑战在于L1 RF的替换策略和一致性管理。这些问题在缓存设计中已有成熟的解决方案,可以直接借鉴。

层次化寄存器文件的命中率分析

L1 RF的有效性取决于其命中率——即指令的源操作数在L1 RF中找到的概率。由于程序具有时间局部性(刚写入的值很快被读取),L1 RF的命中率通常很高。

性能分析 12 — 层次化寄存器文件的命中率

以下模拟数据展示了不同L1 RF大小下的命中率(2-Cluster配置,256个物理寄存器,SPEC CPU整数基准平均值):

L1 RF项数命中率L2 RF访问频率等效IPC损失
878%22%3.2%
1689%11%1.5%
2494%6%0.8%
3297%3%0.4%

16\sim24项的L1 RF可以捕获89%\sim94%的寄存器读取,将等效IPC损失控制在1.5%以下。相比完全复制256项寄存器文件的面积,16项L1 RF的面积仅为其6%——这是非常划算的权衡。

写直通与写回策略

层次化寄存器文件的写入策略也有两种选择,类似于缓存的写策略:

  • 写直通(Write-Through):每次FU产生结果时,同时写入L1 RF和L2 RF。L2 RF始终保持最新,但需要每周期都有L2 RF写入操作。

  • 写回(Write-Back):结果先写入L1 RF,当L1 RF条目被替换时才写回L2 RF。这减少了L2 RF的写入频率,但增加了L1 RF替换逻辑的复杂度,且在L1 RF条目被替换之前L2 RF可能持有旧值。

大多数设计倾向于写直通策略,因为寄存器文件的写入频率远低于数据缓存,且写直通保证了L2 RF的一致性,简化了跨Cluster读取的逻辑。

三种方案的综合比较

设计权衡 3 — 寄存器文件组织方案的选择

三种寄存器文件组织方案各有适用场景:

完全复制适用于物理寄存器数量较少(\leq128个)、Cluster数量较少(2个)的设计。在这种配置下,复制的面积开销可以接受甚至有面积优势(因为端口数减少),且IPC影响最小。Alpha 21264(80个物理寄存器、2-Cluster)是这种方案的典范。

分区适用于面积极度受限但可以容忍较大IPC损失的设计,例如嵌入式处理器或能效优先的E-core。分区方案避免了任何面积翻倍,但跨分区读取的50%概率会导致显著的IPC损失。

层次化适用于物理寄存器数量较多(\geq256个)、需要高IPC但无法承受完全复制面积开销的设计。这是现代高性能处理器最可能采用的方案——通过16\sim32项的L1 RF捕获90%以上的寄存器访问,将L2 RF的大面积开销限制在较低的访问频率下。

在实践中,不同的处理器可能对不同类型的寄存器文件采用不同的方案——例如,整数寄存器文件采用完全复制(因为整数寄存器数量相对较少),而浮点/SIMD寄存器文件采用层次化(因为256位或512位的SIMD寄存器文件面积巨大,完全复制不经济)。

Cluster互联拓扑

当Cluster数量超过2个时,Cluster之间的互联拓扑成为一个重要的设计决策。不同的拓扑在延迟、带宽、面积和功耗方面各有权衡。

全连接互联

在全连接拓扑中,每对Cluster之间都有专用的直连通路。KK个Cluster需要K(K1)/2K(K-1)/2对双向连接。

全连接的优势与局限

全连接的主要优势是延迟统一——任何两个Cluster之间的通信都只需1个额外周期,调度器不需要区分不同的远程Cluster。但布线资源需求随Cluster数量的平方增长:

  • 2-Cluster:1对连接——2条双向通路。

  • 3-Cluster:3对连接——6条双向通路。

  • 4-Cluster:6对连接——12条双向通路。

  • 8-Cluster:28对连接——56条双向通路。

对于4-Cluster以上的配置,全连接互联的布线开销已经非常大。此外,远端Cluster之间的物理距离可能很长,导致难以在1个周期内完成传输。

环形互联

环形拓扑(Ring Topology)将KK个Cluster排列成一个环,每个Cluster只与相邻的2个Cluster直连。数据可以沿环的两个方向传输,最远的两个Cluster之间的通信需要经过K/2\lfloor K/2 \rfloor跳。

环形互联的延迟特征

KK-Cluster的环形拓扑中,Cluster ii到Cluster jj的跨Cluster延迟为:

d(i,j)=min(ij,Kij)×Thopd(i, j) = \min(|i - j|, K - |i - j|) \times T_{\text{hop}}

其中ThopT_{\text{hop}}是相邻Cluster之间的单跳延迟(通常为1个周期)。

对于4-Cluster的环形拓扑,相邻Cluster延迟1周期,对角Cluster延迟2周期。这种非均匀延迟增加了调度器的复杂度——调度器在做分派决策时,需要考虑不同Cluster对之间的不同延迟。

环形互联的适用场景

环形拓扑最适合以下场景:

  • Cluster数量较多(4\geq 4),全连接互联的布线成本过高。

  • 大多数跨Cluster通信发生在相邻Cluster之间(局部性好),远距离通信较少。

  • 物理版图上Cluster自然排列成一行或一圈(例如沿芯片边缘排列)。

在VLIW处理器和DSP中,环形互联的Cluster结构相当常见(如TI TMS320C6x系列的8个功能单元排列成2个数据通路组,每组内部全连接,组间通过交叉通路连接)。在超标量处理器中较少见,因为超标量处理器的Cluster数量通常不超过3个,全连接互联已经足够。

值得注意的是,环形拓扑中非均匀延迟的问题可以通过Cluster感知的分派策略来缓解——分派逻辑不仅考虑源操作数的生产者在哪个Cluster,还考虑从生产者Cluster到目标Cluster的跳数(hop count)。优先选择跳数最小的Cluster,可以将大多数跨Cluster通信控制在1跳(1个额外周期)以内。

交叉条互联

交叉条互联(Crossbar Interconnect)通过一个集中式的交叉开关连接所有Cluster。任何Cluster都可以在1个周期内向任何其他Cluster发送数据(假设交叉条的延迟足够低)。

交叉条的优势是延迟统一且最短(1个额外周期)。但其面积和功耗开销较大——一个K×KK \times K的交叉条的面积与K2K^2成正比。对于2\sim3个Cluster,交叉条与全连接等效;对于4个以上的Cluster,交叉条可能比全连接更规整、更易于物理实现。

交叉条的另一个优势是带宽可配置性:通过控制交叉条的路由逻辑,可以在不同周期为不同Cluster对分配不同的带宽。例如,在某个周期Cluster 0产生了3个结果需要发送到Cluster 1,而Cluster 2和Cluster 3之间没有数据需要传输——交叉条可以将所有带宽集中分配给Cluster 0\toCluster 1的通路。这种动态带宽分配在全连接拓扑中不可能实现(每对Cluster的通路带宽是固定的),但在交叉条中可以通过仲裁逻辑实现。

硬件描述 5 — 跨Cluster互联拓扑的比较

下表总结了三种互联拓扑的关键特征(以4-Cluster为例):

特征全连接环形交叉条
连接数12(双向)8(双向)1个4×44 \times 4开关
最大延迟1周期2周期1周期
延迟是否均匀
布线面积大(但规整)
可扩展性
调度器复杂度

对于2\sim3个Cluster,全连接是最佳选择(简单且延迟统一)。对于4个以上的Cluster,环形或交叉条更实用——环形节省布线面积但引入非均匀延迟,交叉条保持均匀延迟但面积较大。

Cluster与SMT的交互

在支持同步多线程(SMT)的处理器中,分簇设计与线程调度之间存在有趣的交互。本节讨论SMT如何影响Cluster的利用率,以及如何利用Cluster来改善SMT的效率。

SMT对Cluster负载均衡的影响

在单线程执行时,分簇处理器可能面临严重的负载不均衡——某些Cluster因为指令依赖链的集中而过载,其他Cluster则空闲。SMT可以显著缓解这个问题:来自不同线程的指令具有独立的依赖链,它们可以被自然地分配到不同的Cluster中,从而提高所有Cluster的利用率。

线程感知的分派策略

在SMT + 分簇的处理器中,分派逻辑可以采用线程感知(thread-aware)的分派策略:

  • 线程绑定(Thread Binding):将线程0的指令优先分配到Cluster 0,线程1的指令优先分配到Cluster 1。这种策略最小化了跨Cluster通信(因为同一线程的指令在同一Cluster内部通过旁路传递数据),但可能导致负载不均衡(如果两个线程的指令量差异很大)。

  • 线程交织(Thread Interleaving):来自不同线程的指令按交织方式分配到各Cluster。这种策略负载均衡更好,但跨Cluster通信增加(因为同一线程的依赖指令可能被拆分到不同Cluster)。

  • 混合策略:在同一线程的指令间使用依赖感知分配,在不同线程间使用负载均衡分配。这结合了两种策略的优点。

性能分析 13 — SMT对分簇处理器性能的影响

以下模拟数据展示了2-Cluster处理器在单线程和2线程SMT模式下的Cluster利用率和吞吐量:

模式CL0利用率CL1利用率总吞吐量(归一化)
单线程72%58%1.00
2-SMT(线程绑定)70%68%1.35
2-SMT(线程交织)66%65%1.28
2-SMT(混合)71%69%1.38

SMT将两个Cluster的利用率差距从14%(72% vs. 58%)缩小到不到3%,并将总吞吐量提升了35%\sim38%。线程绑定策略比线程交织更有效,因为它保持了同一线程内的旁路局部性。混合策略进一步优化了结果。

Cluster隔离与安全性

在SMT处理器中,分簇还有一个额外的好处:安全隔离。不同线程的指令在不同Cluster中执行时,它们不共享旁路网络——一个线程通过旁路网络的时序变化无法直接影响另一个线程的执行。这在一定程度上缓解了基于时序侧信道(timing side channel)的安全攻击。

旁路网络作为侧信道的风险

在没有分簇的处理器中,两个SMT线程共享同一个全连接旁路网络。攻击者线程可以通过以下方式推断受害者线程的执行行为:

  1. 端口竞争侧信道:攻击者发射与受害者竞争同一执行端口的指令。如果受害者占用了某个端口,攻击者的指令会被延迟——通过测量这个延迟,攻击者可以推断受害者正在执行什么类型的指令。

  2. 旁路竞争侧信道:如果旁路网络的某些MUX输入被受害者的数据占用,攻击者指令的操作数选择可能受到影响(例如MUX仲裁延迟的微小变化)。

当两个线程被分配到不同的Cluster时,它们使用独立的组内旁路网络——攻击者无法通过旁路网络的竞争来推断受害者的行为。跨Cluster的共享资源(如跨Cluster传输寄存器和远程唤醒总线)仍然是潜在的侧信道,但其信息泄露量远小于共享的全连接旁路网络。

线程分区的Cluster分配

为了最大化安全隔离效果,分派逻辑可以实施严格的线程分区:线程0的指令只进入Cluster 0,线程1的指令只进入Cluster 1。这完全消除了两个线程在执行引擎内部的资源共享,但代价是牺牲了跨线程的负载均衡——如果一个线程的指令比另一个多得多,分区策略会导致一个Cluster过载而另一个Cluster空闲。

在安全不是首要考虑的场景下,可以放松分区约束,允许两个线程的指令混合分配到不同Cluster。在需要高安全性的场景(如云环境中不同租户的线程共享同一物理核心)下,严格的线程分区分簇是一个有效的缓解措施。

Cluster对SMT吞吐量的提升机制

分簇对SMT吞吐量的提升来自两个机制:

第一,消除了跨线程旁路依赖。在不分簇的设计中,来自不同线程的指令可能恰好被调度到相邻的流水线槽中,导致旁路网络需要同时传递两个线程的数据——增加了MUX的竞争和延迟。在分簇设计中,如果两个线程被分配到不同Cluster,它们的旁路数据流完全独立,不存在竞争。

第二,提高了IQ的有效利用率。在不分簇的设计中,SMT的两个线程共享一个大的IQ。当一个线程的指令突发性地占据大量IQ条目时,另一个线程可能因为IQ满而被阻塞。在分簇设计中,每个Cluster有独立的IQ,一个线程(在Cluster 0的IQ中)的突发行为不会直接影响另一个线程(在Cluster 1的IQ中)。

这两个机制使得分簇的SMT处理器比不分簇的SMT处理器有更好的公平性(fairness)——两个线程之间的性能干扰更小,每个线程都能获得更可预测的性能。

设计提示

分簇与SMT的结合是一个"一石二鸟"的设计选择——分簇不仅解决了旁路网络的物理实现问题,还为SMT提供了自然的线程隔离和负载均衡机制。在设计支持SMT的宽发射处理器时,应该将Cluster拓扑与线程数量同步考虑——例如,2线程SMT + 2-Cluster是一个非常自然的匹配。Alpha 21264虽然不支持SMT,但其双Cluster结构为后来的SMT处理器(如Intel Pentium 4的Hyper-Threading)提供了重要的设计启示。

Cluster设计的综合考量

本节将前面各节的讨论综合起来,形成一个系统的分簇设计流程和决策框架。

分簇设计的决策流程

分簇设计的决策流程通常包括以下步骤:

  1. 确定FU总数和类型:基于目标IPC和工作负载特征,确定所需的整数ALU、Load/Store、浮点/SIMD等FU的数量。

  2. 第一层分簇——按功能类型:将整数、浮点/SIMD和Load/Store分成独立的Cluster。这一步几乎所有处理器都会做,因为这三类FU操作不同的寄存器文件和数据通路。

  3. 评估每个功能Cluster内的旁路复杂度:对于每个功能Cluster,计算全连接旁路网络的通路数、MUX扇入和布线面积。如果超过物理可行的阈值(通常是4\sim5的MUX关键扇入),则需要进一步分簇。

  4. 第二层分簇——对称或非对称:在需要进一步分簇的功能Cluster内部,选择对称或非对称的分簇方案。确定每个子Cluster的FU数量和类型。

  5. 确定跨Cluster互联拓扑:选择全连接、环形或交叉条等互联方式,确定跨Cluster延迟。

  6. 设计分派策略:基于Cluster拓扑和延迟配置,设计依赖感知的分派策略。通过模拟验证IPC影响。

  7. 确定寄存器文件组织:选择完全复制、分区或层次化方案,确保寄存器文件与Cluster拓扑兼容。

  8. 物理设计验证:在实际版图上验证Cluster内部的时序收敛和跨Cluster通路的延迟是否符合预期。如果不满足,迭代调整Cluster数量和拓扑。

分簇设计的关键指标

评估分簇设计质量的关键指标包括:

  • IPC损失:相对于理想全连接方案的IPC下降比例。目标是<5%<5\%

  • 频率增益:分簇带来的时钟频率提升比例。目标是>10%>10\%以弥补IPC损失。

  • 面积开销:寄存器文件复制和跨Cluster互联的面积增加。目标是<20%<20\%的执行引擎面积增加。

  • 功耗影响:旁路网络功耗的降低 vs. 寄存器文件复制带来的功耗增加。理想情况下净功耗降低。

  • 跨Cluster通信比例:所有数据旁路中需要跨Cluster传输的比例。依赖感知分配下,目标是<25%<25\%

性能分析 14 — 分簇设计的综合评估示例

下表展示了一个8-wide整数处理器(6个ALU + 2个AGU)的三种设计方案的综合评估:

指标全连接2-CL(3+3 ALU)3-CL(2+2+2 ALU)
MUX关键扇入743
IPC(归一化)1.000.960.92
频率潜力基准+12%+18%
性能(IPC×\timesF)1.001.0751.086
面积开销基准+15%+25%
设计复杂度中低

2-Cluster和3-Cluster方案的总性能都优于全连接方案。3-Cluster方案的性能略高,但设计复杂度显著增加。在大多数实际项目中,2-Cluster是更实用的选择——它在性能、面积和设计复杂度之间提供了最佳平衡。

Cluster设计的RTL实现注意事项

从微架构描述到RTL实现,分簇设计有几个需要特别注意的工程细节。

跨Cluster信号的时序约束

在RTL设计中,跨Cluster信号必须在静态时序分析(STA)中被正确约束。常见的做法是:

  • 将跨Cluster旁路通路定义为多周期路径(multicycle path)——发送端在第NN周期锁存,接收端在第N+1N+1周期采样。STA工具据此放松时序约束,允许更长的传播延迟。

  • 在跨Cluster标签广播通路上插入管道寄存器(pipeline register),将长距离信号分割成两段短距离信号,确保每段都满足单周期时序。

  • 对跨Cluster互联的物理通道进行预留布线(pre-routed channel),在版图设计的早期阶段就为跨Cluster通路分配专用的金属通道,避免在自动布线阶段因拥塞导致绕路。

验证中的分簇相关问题

分簇处理器的功能验证面临独特的挑战:

  1. 寄存器文件一致性验证:在完全复制方案中,需要验证所有Cluster的寄存器文件副本在每个可观察点(例如精确中断时)是一致的。这需要专用的检查器(checker)逻辑或断言。

  2. 跨Cluster依赖的正确处理:需要验证当指令的源操作数通过跨Cluster旁路获得时,数据值和时序都是正确的。边界情况包括:源操作数同时通过本地旁路和远程旁路可达时的优先级选择。

  3. 分派策略的负载均衡:需要用统计方法验证分派策略在各种工作负载下都不会导致严重的负载不均衡——例如,某个Cluster的IQ持续满载而其他Cluster空闲超过NN个周期。

功耗优化技术

在分簇处理器的RTL实现中,以下功耗优化技术特别重要:

  • 旁路网络的门控时钟:每个旁路通路的驱动器使用门控时钟——当该通路上没有有效数据时(即对应FU未产生结果),关闭驱动器的时钟以消除翻转功耗。在典型执行中,每个周期只有30%\sim50%的FU产生有效结果,门控时钟可以节省旁路网络50%\sim70%的动态功耗。

  • 空闲Cluster的时钟门控:当某个Cluster的IQ为空且没有正在执行的指令时,可以关闭该Cluster的所有时钟(包括FU、旁路网络和本地寄存器文件的时钟),实现Cluster级别的功耗节省。这在负载不均衡的场景下特别有效。

  • 跨Cluster通路的按需激活:跨Cluster旁路通路通常不需要每个周期都活跃。可以使用预测逻辑——在分派阶段预判下一周期是否有跨Cluster旁路需求,如果没有则提前关闭跨Cluster驱动器。

硬件描述 6 — 分簇处理器的门控时钟层次

一个典型的2-Cluster处理器的门控时钟层次可以组织为三级:

  1. L1门控——FU级别:每个FU单独门控。当FU在某周期不执行指令时,关闭该FU的时钟。这是最细粒度的门控,节省单个FU的翻转功耗。

  2. L2门控——Cluster级别:当整个Cluster空闲时,关闭Cluster内所有FU、本地旁路网络和本地寄存器文件的时钟。这在Cluster之间负载不均衡时有效。

  3. L3门控——跨Cluster级别:当没有跨Cluster旁路需求时,关闭跨Cluster传输寄存器和驱动器的时钟。这通常可以关闭30%\sim50%的周期。

三级门控相互独立,可以叠加应用。估算表明,三级门控总共可以减少执行引擎动态功耗的30%\sim45%。

未来趋势:超宽处理器与分簇

随着处理器继续向更宽的发射方向演进(10-wide甚至更宽),分簇技术将面临新的挑战和机遇。

工艺缩小对分簇的影响

在3 nm及以下的工艺节点,导线电阻持续增大(RC延迟恶化),这使得长距离旁路更加困难。这对分簇设计有两方面的影响:

  • 更需要分簇:由于导线延迟的恶化,即使是4个FU的全连接旁路,在最先进工艺下也可能面临时序挑战。分簇的"门槛"可能从6个FU降低到4个FU。

  • 跨Cluster延迟可能增加:相同物理距离下,导线延迟更大,跨Cluster的1周期额外延迟可能变成2周期——这将显著增加IPC损失。设计者需要更紧凑的版图或更先进的互联技术(如背面供电释放正面布线资源)来维持1周期的跨Cluster延迟。

3D集成与分簇

3D堆叠技术为分簇设计提供了新的维度。如果两个Cluster可以垂直堆叠(一个在上层芯片、一个在下层芯片),它们之间的通信可以通过极短的硅通孔(TSV)或混合键合(hybrid bonding)连接完成——跨Cluster延迟可能缩短到接近组内旁路的水平。这将使得更多的Cluster成为可能,而不会显著增加跨Cluster延迟惩罚。

处理器宽度的实际上限

从Alpha 21264的4-wide到Apple M系列的8-wide,处理器的发射宽度在25年间翻了一倍。继续增加到10-wide或12-wide需要8\sim10个整数ALU,这在分簇设计下需要3\sim4个Cluster。前面的分析表明,4-Cluster的IPC损失约10%,频率增益可能不足以弥补——这暗示了超标量处理器的宽度可能正在接近一个"软极限"。

超越这个极限可能需要根本性的架构创新,例如:

  • VLIW/EPIC风格的显式并行:将Cluster暴露给编译器,由编译器直接指定指令到Cluster的映射,消除硬件分派的开销。

  • 多线程:通过SMT(同步多线程)利用多个Cluster的并行度,而不依赖单线程ILP。

  • 分片执行(sliced execution):将整个执行引擎分成完全独立的"片"(slice),每片有自己的IQ、RF和FU,片之间通过异步消息传递通信。

背面供电(BSPDN)对分簇的影响

Intel和TSMC都在推进背面供电网络(Backside Power Delivery Network, BSPDN)技术,预计在2 nm及以下节点广泛采用。在传统设计中,电源线和信号线共享正面的金属层,电源网格占据了约20%\sim30%的布线资源。将电源网格移到芯片背面后,正面金属层的布线资源大幅增加——这对旁路网络这种布线密集型结构是重大利好。

背面供电可能使得更宽的全连接旁路网络重新变得可行。例如,在传统正面供电的5 nm工艺下,6个ALU的全连接旁路需要约200 μ\mum的布线通道,占执行引擎宽度的40%\sim50%。如果背面供电释放了20%\sim30%的布线资源,6-ALU全连接旁路可能只需占用25%\sim35%的通道——回到可接受的范围。这意味着分簇的"门槛"可能从6个FU重新提升到8个FU,推迟了分簇的必要性。

然而,背面供电不能改变MUX延迟——MUX是逻辑门而非导线,其延迟由工艺节点决定。因此,MUX扇入仍然是分簇设计的硬约束。背面供电只是缓解了布线瓶颈,并未消除分簇的根本需求。

分簇设计的长期演化方向

综合以上分析,分簇技术在未来处理器中可能沿以下方向演化:

  1. 动态可重构Cluster:根据工作负载特征动态调整Cluster边界——例如,在单线程模式下使用2-Cluster配置以最大化单线程IPC,在多线程模式下切换到4-Cluster配置以最大化吞吐量。动态重构需要可编程的旁路网络互联,增加了硬件复杂度,但提供了更好的灵活性。

  2. 自适应分派策略:使用机器学习或运行时反馈来动态调整分派策略的参数(如不均衡阈值、关键路径估计权重等)。现代处理器已经在分支预测中广泛使用自适应算法,将类似技术应用于Cluster分派是自然的延伸。

  3. 编译器与硬件的协同优化:通过ISA扩展(如指令提示位)让编译器向硬件传递Cluster亲和性信息,减少硬件分派逻辑的负担。这种方式在VLIW处理器中已经被验证有效,但在超标量处理器中需要谨慎设计以避免破坏二进制兼容性。

设计权衡 4 — 分簇设计的历史回顾与展望

分簇技术的25年发展历程展示了一个有趣的模式:

  • 1998年(Alpha 21264):4-wide发射,2个ALU,2-Cluster。分簇是为了实现当时工艺下的最高频率。

  • 2017年(AMD Zen 1):6-wide发射,4个ALU,按功能类型隐式分簇。工艺进步使得4-ALU全连接旁路仍然可行。

  • 2024年(AMD Zen 5、Apple M4):8-wide发射,6个ALU,可能的2-Cluster。再次触及全连接旁路的物理极限,分簇再度成为必需。

  • 2030年(推测):可能的10-wide发射,8个ALU,需要3-Cluster或层次化分簇。背面供电和3D集成可能提供新的设计自由度。

每次工艺进步都短暂地推迟了分簇的必要性(通过提供更多布线资源和更快的逻辑门),但处理器设计者总是会用尽工艺提供的裕量来增加执行宽度——最终再次触及全连接旁路的极限。分簇技术与这种"宽度-物理极限"的拉锯战共同演化,并将在可预见的未来继续扮演核心角色。

本章从宽发射处理器中旁路网络面临的物理极限出发,系统讨论了分簇(Clustering)技术的动机、发射队列的分簇组织、分簇旁路网络的设计,以及Cluster感知的调度策略。通过Alpha 21264、AMD Zen系列、Apple M系列和Intel处理器四个案例,我们看到分簇设计从1998年至今一直是高性能处理器的核心技术之一。分簇的本质是一种物理设计驱动的微架构决策——它将全局的、物理上不可行的全连接结构替换为局部的、物理上可行的分块互联结构,以少量的性能损失换取了宽发射处理器的物理实现可能性。

Cluster数量的选择——2个、3个、4个还是非对称——反映了IPC、频率、面积和设计复杂度之间的多维权衡。在当前的技术条件下,2\sim3个Cluster是最常见的选择,每个Cluster内3\sim4个FU是旁路网络复杂度的"甜蜜点"。随着工艺继续缩小和处理器持续追求更宽的发射,分簇技术将继续演化,可能与3D集成、背面供电等新型物理设计技术结合,突破当前的宽度瓶颈。

以下表格总结了本章讨论的主要设计决策和推荐选择:

设计决策常见选择关键考虑因素
Cluster数量2\sim3IPC损失 vs. 频率增益
分簇维度功能类型 + 对称第一层按功能,第二层按对称性
寄存器文件完全复制或层次化物理寄存器数量、面积预算
分派策略依赖感知 + 负载均衡跨CL通信<<25%为目标
跨CL延迟1个额外周期必须\leq1周期,否则IPC损失过大
IQ组织分布式或混合式每CL的IQ\approx4\sim6×\timesFU数
互联拓扑全连接(\leq3 CL)>>3 CL考虑环形或交叉条
Load-ALU通路专用快速旁路0额外延迟,最高优先级
SMT交互线程绑定到Cluster安全场景用严格分区

这些设计决策之间并非独立——Cluster数量影响IQ大小,IQ组织影响分派策略的复杂度,寄存器文件组织影响跨Cluster通信的频率。设计者需要将这些决策作为一个整体进行联合优化,通过RTL级的性能模拟和物理设计的迭代反馈,找到满足所有约束的最优解。

性能分析 15 — Cluster间通信延迟对IPC的影响量化

本算例量化Cluster间通信延迟对处理器IPC的影响。

已知条件:

  • 处理器配置:6-wide,双Cluster(每Cluster 3个执行端口)

  • 无Cluster延迟时的基线IPC:IPC0=3.2\text{IPC}_0 = 3.2

  • Cluster内旁路延迟:0周期(同周期可用)

  • Cluster间额外延迟:Δ=1\Delta = 1周期

  • 跨Cluster依赖比例:p=30%p = 30\%(约30%的数据依赖需要跨Cluster传递)

第一步:估算跨Cluster依赖的有效周期惩罚。

每条跨Cluster依赖的指令,其消费者指令的发射延迟增加Δ=1\Delta = 1周期。在关键依赖链上,每次跨Cluster传递相当于在关键路径上插入1个气泡。

第二步:估算关键路径上的跨Cluster比例。

假设平均关键依赖链长度为L=8L = 8条指令(典型整数程序的平均值)。每条链上约p×L=0.30×8=2.4p \times L = 0.30 \times 8 = 2.4条指令的依赖需要跨Cluster。

第三步:计算关键路径拉伸比。

无Cluster时,关键路径长度为L=8L = 8周期。有Cluster后,关键路径长度增加为L+p×L×Δ=8+2.4×1=10.4L + p \times L \times \Delta = 8 + 2.4 \times 1 = 10.4周期。关键路径拉伸因子α=10.4/8=1.30\alpha = 10.4 / 8 = 1.30

第四步:估算IPC下降。

IPC与关键路径长度近似成反比(在资源不饱和的情况下):

IPCclusterIPC0α=3.21.302.46\text{IPC}_{\text{cluster}} \approx \frac{\text{IPC}_0}{\alpha} = \frac{3.2}{1.30} \approx 2.46

IPC下降量为3.22.46=0.743.2 - 2.46 = 0.74,下降百分比约为23%23\%

第五步:分析跨Cluster比例的敏感性。

跨Cluster依赖比例 pp拉伸因子 α\alphaIPC下降
10%1.10\sim9%
20%1.20\sim17%
30%1.30\sim23%
40%1.40\sim29%
50%1.50\sim33%

结论:将跨Cluster依赖比例控制在25%以下是保证IPC损失<<20%的关键。这解释了为什么现代处理器的Cluster调度器投入大量逻辑进行依赖感知的指令分配——将有依赖关系的指令尽量分配到同一Cluster中。Alpha 21264的设计经验表明,通过智能分派,实际的跨Cluster依赖比例可以降至20%\sim25%,使IPC损失控制在5%\sim8%的可接受范围内(低于上述简化模型的估计,因为并非所有跨Cluster依赖都位于关键路径上)。

Cluster结构解决了执行单元之间的旁路网络物理瓶颈,但处理器中还有另一类同样关键的数据传递问题:Load指令如何获取尚在Store Buffer中的最新数据?第 36.0 章将讨论存储器消歧(Memory Disambiguation)和Store-to-Load转发机制——这是旁路思想在内存层面的延伸。我们将看到,Store Buffer的转发逻辑面临与旁路网络类似的O(N2)O(N^2)搜索复杂度问题,而Alpha 21264的Store Wait Table正是对这一问题的经典投机解法。

在下一章中,我们将讨论乱序执行引擎中的另一个关键结构——调度器(Scheduler)的高级设计话题,包括投机唤醒(speculative wakeup)、多级调度(multi-level scheduling)以及调度器与Cluster结构之间更深层次的交互。

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