CPU Wiki: Sandy Bridge Microarchitecture 前端(上)

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,而会产生好的结果。

CPU Wiki: Sandy Bridge Microarchitecture 前端(上)_第2张图片
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 保留了更长的历史,并且存储了更有效的历史信息


Baidu Intel完全重新了一个分支预测单元(BPU),精确度更高,并在三个方面进行了创新。
第一,标准的BPU都是2-bit预测器,每个分支都使用相关可信度(强/弱)进行标记。Intel发现,这种双模预测器所预测的分支几乎都是强可信度的,因此SNB里多个分支都使用一个可信度位,而不是每个分支对应一个可信度位,结果就是在分支历史表中同样的位可以对应更多分支,进而提高预测精确度。
第二,分支目标同样做了翻新。之前的架构中分支目标的大小都是固定的,但是大多数目标都是相对近似的。SNB现在支持多个不同的分支目标大小,而不是一味扩大寻址能力、保存所有分支目标,因而浪费的空间更少,CPU能够跟踪更多目标、加快预测速度。
第三,提高分支预测器精度的传统方法是使用更多的历史位,但这只对要求长指令的特定类型分支有效,SNB于是将分支按照长短不同历史进行划分,从而提高预测精度。

Instruction Queue & MOP-Fusion 预解码过的指令会被发送到Instruction Queue(IQ)。在Nehalem中,指令队列增长到18 entry,被两个线程共享。Sandy Bridge 增加了数目,每个线程20,总计40。

CPU Wiki: Sandy Bridge Microarchitecture 前端(上)_第3张图片
指令队列的一个关键优化是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。

Decoding
每周期预解码器可以发送4条(如果其中一条指令为macro fusion则为5条)指令给译码器。像取指单元一样,译码器每周期也在线程之间切换。译码器读取macro-ops 然后发送规整的定长的uOPs。Sandy Bridge的译码器或多或少基本和Nehalem一致。和他的前辈一样,Sandy Bridge使用四个译码器。译码器是非对称的。第一个译码器Decoder 0是一个复杂译码器,其他的是简单译码器。简单译码器可以翻译发射单条fused-uOP的指令。然而,复杂译码器可以翻译1~4条fused-uOP的指令。译码单元输出指令的上限为4uops。这意味着,如果复杂译码器想要输出超过一条的指令,那么就有一个简单译码器不工作。

CPU Wiki: Sandy Bridge Microarchitecture 前端(上)_第4张图片
Sandy Bridge 引入了一组256-bit SIMD指令集叫做AVX。这项扩展将以前存在的16个128bit的XMM寄存器扩展到256-bit YMM 寄存器,用于浮点向量操作(注意Haswell进一步扩展到了整数操作 )。大部分的新的AVX指令被设计为是简单指令,可以被简单译码器译码。

欢迎关注我的公众号《处理器与AI芯片》

你可能感兴趣的:(Microarchiture,计算机体系结构)