CPU Wiki: Sandy Bridge Microarchitecture 1
Sandy Bridge 可以看做是自从NetBurst和P6之后的一个全新microarchitecture。Sandy Bridge回溯了最去的drawing board阶段,从P6和NetBurst引入了很多有益的结构。尽管NetBurst是一个有严重瑕疵的结构,但是它引入了一些重要的创新,这些在Sandy Bridge中被重新实现并增强。它与一直到Nehamlem基本都没有引入P4,P6的结构的早期Core结构不同。 Sandy Bridge引入并增强了前辈们的优点。
PipeLine
SandyBridge 专注于挖掘性能,降低功耗。Intel将降低功耗和提升性能作为重点,达到了非线性的performance-to-power的提高。这些增强在frond-end和back-end中都可以看到。
Frond-end
前端的挑战主要是从memory中读取复杂的X86指令,解码,并且将它们传递到执行单元,换而言之,前端需要能够持续的将足够的uOps发送到instruction code stream中,以保证后端能够忙起来。当后端没有被充分利用的时候,core是无法发挥他的全部性能的。弱的或者是没有发挥全部能力的前端将会严重影响后端,最终导致糟糕的性能。在Sandy Bridge的case中,这个挑战被重定向的分支和X86指令自身的复杂本性进一步复杂化。
Fetch & pre-decoding
到达core的内存块,要么来自cache,要么是通过ring从其他cache 搬来,在一些偶尔的情况下,也会从主存中搬来。首先,指令需要从L2Cache取出,存入L1cache。L1cache是32KB,8 way 组相连。指令cache的大小与Nehalem相同,但是组相连数扩展到8-way。Sandy Bridge 使用过16byte的取数据窗口取指。这个窗口的大小好几代都没有变过。每个周期最多取16byte。要注意,取指是在两个线程中公平的切换。所以每个线程都可以在另一个周期取指。这时他们还是marco-ops(X86变长指令)。指令被存入pre-decode buffer用于最初的准备工作。
X86指令是复杂的,变长的,是变长编码并且可以包括不同的操作。在pre-decode buffer中,指令的边界被检测并标记到。这一一项相当困难的工作,因为每条指令的长度都可以从1byte变化到15byte。甚至决定一个一条指令的长度需要检测指令的好几个byte。除了边界检测,指令前缀也被解码,而且要检测一些特性,比如分支。和之前的微架构一样,预解码器有着6 macro-ops的吞吐量,直到16byte被完全消化。需要注意的是,预解码器不会没消化完16byte就去取新的16byte block。比如,如果加载了一个新的数据块,产生了7条指令。第一个周期,6条指令被处理,第二个周期一整个周期会浪费在剩下的1条执行上。这样吞吐量就会是小于预期的3.5。如果是5条指令,前四条1byte,那么第一个周期处理4条指令,第二个周期只能处理一条指令,吞吐量2.5。需要注意还存在特殊的情况Length-changing prefix(LCPs)会导致额外的预解码损耗。真实的代码通常低于4byte,而会产生好的结果。
Branch Predictor
取指操作和负责预测指令流向的分支预测单元(BPU)是同时工作的。所有的分支利用BPU预测其方向,包括return,非直接调用&跳转,直接调用&跳转,以及条件分支。与Intel 位架构的每一代处理器相同,分支预测也被提高了。分支预测器的一个提高会直接提高性能,降低功耗。由于深长的流水线,flush操作是相当昂贵的,会放弃in-flight的150条指令。在Nehalem中创造并引入Sandy Bridge的一个巨大的变化就是将frond-end 和 back-end的BPU相关进行解耦。在Nehalem之前,整条流水线都需要被彻底flush,然后前端才能重新操作。在Nehalem中这个被重新设计,前端可以在知道了正确的方向后就立刻开始译码,与此同时,后端仍然在flush预测错误的uOps。这可可以降低预测目标错误的代价。此外,Sandy Bridge中的分支预测器也被彻底重新设计了。分支预测期引入了Nehalem中的一些机制:Indirect Target Array(ITA), branch target buffer(BTB), Loop Detector(LD) 和 renamed return stack buffer(RSB)。
对于近返回(near return),Sandy Bridge 有16 entry return stack buffer。 BTB是单独的单级结构,保存了两倍于Nehalem L1/2 BTB entry的数目。这个改变应该可以提高预测覆盖率。有趣的是,在Nehalem之前的架构Core中,也是使用的单级结构。因为对于大多数的分支对于每条分支不需要较多的bit,因此对于较大 displacements的分支,使用了一个单独的table。Sandy Bridge 的 4096 目标的 BTB table,通过1024组4路组成。
全局历史信息表在Sandy Bridge中没有增大,但是通过移除不能提升预测正确率的历史来提高了性能。此外,全局历史信息表为数据dependent behavior 保留了更长的历史,并且存储了更有效的历史信息
指令队列的一个关键优化是macro-op fusion。在一些case中,Sandy Bridge 可以将两条macro-ops 融合为单独的一条复杂op。如果检测到指令流中test或者compare的后续跟随着一条条件跳转,那么他们会被转化成单独的一条 compare&branch 指令。在Sandy Bridge中,Intel扩大了macro-op fusion能力的范围。Macro-fusion 现在可以将比如ADD和SUB这样的指令与JUMP融合。这意味着,更多的case是可以融合的。或许最重要的case是典型的counter后面跟随着一个条件分支的循环。这些就可以被融合了。这些被噢鞥和的指令在整条流水线上一直保持着融合的状态,在分支单元执行时,也是一整条被融合的指令,因此从每个位置上都节省了带宽。不过每个周期只能完成一条这样的fusion。
欢迎关注我的公众号《处理器与AI芯片》