Nehalem
Nehalem
中国北京2008年1月8日,英特尔公司发布了首批基于英特尔迅驰处理器技术笔记本上的45纳米(nm)处理器,至此英特尔45纳米技术处理器家族全部产品已经悉数登场。简单说来,Nehalem还是基本建立在Core微架构(Core Microarchitecture)的骨架上,外加增添了SMT、3层缓存、TLB和分支预测的等级化、IMC、QPI和支持DDR3等技术。
目录
1Nehalem技术研究
·总述
·QPI总线技术
·IMC
·SMT
·前端部分
·乱序引擎和执行部分
·缓存结构
·TLB,虚拟化性能
·Nehalem的模块化设计
2Nehalem微架构
3Nehalem代号由来
1Nehalem技术研究
总述
下文中介绍的Nehalem的技术指标主要是以Nehalem-EP(Gainestown)为范例来介绍的,该核心将会用于Xeon DP,就是用于服务器的双路CPU。Nehalem是4核心、8线程、64bit、4超标量发射、乱序执行的CPU,有16级流水线、48bit虚拟寻址和40bit物理寻址。
比起从Pentium 4的NetBurst架构到Core 微架构的较大变化来说,从Core 微架到Nehalem架构的基本核心部分的变化则要小一些,因为Nehalem还是4指令宽度的解码/重命名/撤销。
Nehalem的核心部分比Core 微架构新增加的功能主要有以下几方面:
New SSE4.2Instructions (新增加SSE4.2指令)
Improved Lock Support (改进的锁定支持)
Additional Caching Hierarchy (新的缓存层次体系)
Deeper Buffers (更深的缓冲)
Improved Loop Streaming (改进的循环流)
Simultaneous Multi-Threading (同步多线程)
Faster Virtualization (更快的虚拟化)
Better Branch Prediction (更好的分支预测)
QPI总线技术
Nehalem使用的QPI总线是基于数据包传输(packet-based)、高带宽、低延迟的点到点互连技术(point to point interconnect),速度达到6.4GT/s(每秒可以传输6.4G次数据)。每一条连接(link)是20bit位宽的接口,使用高速的差分信号(differential signaling)和专用的时钟通道(dedicated clock lane),这些时钟通道具有失效备援(failover)。QPI数据包是80bit的长度,发送需要用4个周期。尽管数据包是80bit,但只有64bit是用于数据,其它的数据位则是用于流量控制、CRC和其它一些目的。这样,每条连接就一次传输16bit(2Byte)的数据,其余的位宽则是用于CRC。由于QPI总线可以双向传输,那么一条QPI总线连接理论最大值就可以达到25.6GB/s(2×2B×6.4GT/s)的数据传送。单向则是12.8GB/s。
对于不同市场的Nehalem,可以具有不同的QPI总线条数。比如桌面市场的CPU,具有1条或者半条QPI总线(半条可能是用10bit位宽或单向);DP服务器(双CPU插座)的CPU,每个具有2条QPI总线;而MP服务器(4个或8个CPU插座)的,则每个具有4条或更多的QPI总线。
IMC
Nehalem的IMC(integrated memory controller,整合内存控制器),可以支持3通道的DDR3内存,运行在1.33GT/s(DDR3-1333),这样总共的峰值带宽就可以达到32GB/s(3×64bit×1.33GT/s÷8)。不过还并不支持FB-DIMM,要Nehalem EX(Beckton)才有可能会支持FB-DIMM(Fully Buffered-DIMM,全缓冲内存模组)。每通道的内存都能够独立操作,控制器需要乱序执行来降低(掩盖)延迟。由于有了Core 2近4倍的内存带宽,Nehalem的每个核心支持最大10个未解决的数据缓存命中失败(outstanding data cache miss)和总共16个命中失败,而Core 2在运行中则只支持最大8个数据缓存的和总共14个的命中失败。
IMC能够很显著的降低内存延迟(尤其是对于采用FB-DIMM方案的系统)。下面的Nehalem与Harpertown,我不清楚是什么频率情况下的对比(来自于IDF上的表格,可能Nehalem是3.2GHz)。Nehalem的本地内存延迟大约是Harpertown的60%。Harpertown系统使用的是1.6GT/s的前端总线,所有内存都在一个位置,大约是略低于100ns(纳秒)的延迟,这样Nehalem的内存延迟就是约60ns。对于2个CPU插座的Nehalem来说,使用的是NUMA结构(Non Uniform Memory Access Achitecture,非均匀内存存取架构),远方内存的延迟则要高一些,因为这时对内存的请求和回应需要通过QPI总线,其延迟大约是Harpertown的95%。所以,即使是最糟糕的情况,延迟还是得到了降低。一个有意思的问题是,当使用4个CPU插座的Nehalem时,延迟是否将会被增大?因为这种系统很有可能会使用FB-DIMM,而这意味着将遭受延迟损失,不过远方内存的延迟还是将只会比本地内存慢个约30ns。
对于其它使用IMC和核心互连的多CPU系统(例如EV7、K8、K10),内存延迟也是非均匀的(NUMA)。为了优化性能,操作系统就必须知道延迟差异,并调度那些在同一个CPU上共享数据的进程。Windows Vista是Microsoft的第一个为NUMA进行优化的操作系统,而Linux等则已经很早就可以支持NUMA了。
Nehalem的远方/本地延迟比是约1.5倍。衡量K8的NUMA系数(也就是远方延迟除以本地延迟)在2 CPU系统时也差不多是1.5。而在4 CPU系统时,INTEL将具有优势,因为所有的内存要么都是本地(当QPI总线上没有hop时),或者所有内存都是远方(QPI总线上有一个hop时)。因为使用对角线连接,每个CPU都有QPI总线连接,那么远方内存最多就一跳(1个hop)。而现在的4插座的K8或K10系统,有的内存在HT总线上多达有2个hop。总之,具有更大的NUMA系数,就更需要软件考虑其所使用的内存的位置。作为参考,其中最早一个具备IMC和核心互连的EV7,在其64 CPU的系统中,NUMA系数为1.86-5.21(1-8个hop的情况)。
SMT
同步多线程(Simultaneous Multi-Threading,SMT)技术又重新回归到了Nehalem架构,这最早出现在130nm的P4上。对于打开了SMT的CPU来说,将会遭受到更多的命中失败,并需要使用更多的带宽。所以Nehalem比P4是更适合使用SMT的。另外,在移动和桌面领域的Nehalem有可能将不会支持SMT,它们也不需要3通道内存。
为什么Core 2没有使用SMT?很显然,它是可以做到的。SMT是在节省电力的基础上增加了性能,而且软件支持的基础建设也早就有了。有2个可能的原因:一是Core 2可能没有足够的内存带宽和CPU内部带宽来利用SMT获得优势。通常,SMT能够提升内存级并行(memory level parallelism,MLP),但是对于内存带宽已经成为瓶颈的系统则是个麻烦。而更有可能的原因则是SMT的设计、生效等是很麻烦的,而当初设计SMT是由INTEL的Hillsboro小组主持,而并非是Haifa小组(Core 2是由这个小组负责的)。这样Core 2不使用SMT就避免了冒险。
Nehalem的同步多线程(Simultaneous Multi-Threading,SMT)是2-way的,每核心可以同时执行2个线程。对于执行引擎来说,在多线程任务的情况下,就可以掩盖单个线程的延迟。SMT功能的好处是只需要消耗很小的核心面积代价,就可以在多任务的情况下提供显著的性能提升,比起完全再添加一个物理核心来说要划算得多。这个和以前P4的HT技术是一样的,但比较起来,Nehalem的优势是有更大的缓存和更大的内存带宽,这样就更能够有效的发挥。按照INTEL的说法,Nehalem的SMT可以在增加很少能耗的情况下,让性能提升20-30%。
对于SMT的各线程间所采用的资源共享策略有许多种:
1、复制型—— 线程都可以复制使用
寄存器状态
重命名RSB(重命名返回堆栈缓存)
大页表ITLB
2、静态分配型—— 一般由线程平分
各种主要的缓冲:读取、存储、重排序
小页表ITLB
3、竞争共享—— 由线程动态占有
保留站(RS)
缓存(Cache)
数据TLB(DTLB),L2 TLB
4、不受影响
执行单元
Nehalem同时也降低了同步原语(起始同步),比如LOCK prefix、XCHG和CMPXCHG等指令的延迟。同步原语在多线程编程中是必需的,而多线程的扩展性被同步所限制,通过降低延迟,可以提高现在多线程软件的性能。INTEL宣称,Nehalem的LOCK CMPXCHG指令(其作用是使整个流水线串行化)的延迟是P4的约20%,Core 2的约60%。尽管降低了延迟,但行为仍然和以前的CPU还是一样的,锁定指令(Lock)并不是管道化的,即使后面的操作可以被提前到锁定指令之前来执行。
前端部分
(指令拾取和解码)
1、指令拾取(包括分支预测)
在Nehalem的指令拾取单元(instruction fetch unit)中包含有相关指令指针(relative instruction point,RIP),每个线程状态(thread context)各有一个。在指令拾取单元中还包含有分支预测器,用来预测下一条将被拾取的指令的RIP。对于分支预测器的很多细节,INTEL并没有公布,但它们是适合于工作在SMT模式的。并且Nehalem也将继续使用上一代的那些特殊的分支预测器,比如循环检测器(loop detector),间接预测器(indirect predictor)等。
当分支预测器选定一条分支时,分支目标缓冲(branch target buffer,BTB)就负责预测目标地址。Nehalem使用了2级BTB结构。作为参考,K10使用了一个有2K 项(entry)的BTB用于直接分支,和一个有512项的间接分支目标阵列(indirect branch target array)。Nehalem的两级BTB设计,非常适用于有大量指令代码的任务,例如数据库、ERP和其它的商业应用,通过提高分支预测准确度而提升性能和能效。INTEL没有发布详细的内部结构。下面作出一些有依据的猜测。
有两种可能。一是两个BTB使用同样的预测算法,而一个存取更小一点的历史文件,包含最近时间内所使用的分支RIP和目标RIP。在这种情况下,它们的关系就象L1缓存和L2缓存一样(因为分支目标也具有相当好的地址相关性)。举个例子,比如L1 BTB有256-512项,而更大的L2 BTB则有2K-8K项。如果分支RIP在L1 BTB中没有找到,然后就到L2 BTB中去找,以作出目标预测。
另一种可能(RWT认为这种可能性比较小)则是两级BTB使用不同的预测算法和不同的历史文件。比如L1 BTB使用简单而快速的算法和相对较小的历史文件,而L2 BTB则使用更慢但更准确的算法,而且被配置成是具有优先权的预测器。如果L2 BTB不同意L1 BTB的预测,则它可以撤消(override)L1 BTB的预测,去除掉流水线中错误拾取的指令,而从新预测的RIP处重新拾取指令。这种结构可能性不大,因为它的能效比较低下。对于这种预测器架构,通常的情况是L1和L2 BTB都独立的得出正确的分支目标——这就意味着在大多数的时间里,L2 BTB都是在浪费能源。而L1 BTB错误,L2 BTB是正确的情况,只占非常小的比例。
不过在更早一点的ANANDTECH的文章中有提到认为是第二种方式:通常会遇到这样的情况,L1 BTB作出预测是基于分支的类型,但实际上它并没有历史数据,这样准确度就很低。而L2 BTB有更多的历史数据,就可以提高准确度,而且L2 BTB可以在执行过程中就纠正(L1 BTB所给出的)错误预测,而避免性能损失(这就正是override的情况)。
现在不清楚哪一种观点更正确一些。
Nehalem另一个提升分支目标预测的机制是对返回堆栈缓冲(return stack buffer,RSB)进行了重命名。当发生程序调用时,RSB就记录下地址,这样当结束调用返回时,就从该地址继续执行下去。但是当有很多程序递归调用时,RSB将会溢出,并且如果分支预测错误,那么也将会产生错误的返回地址。Nehalem通过重命名RSB,就避免了溢出。并且错误的分支预测也不会毁坏RSB,只要调用与返回地址是正确配对的,那么就可以从Nehalem的RSB中得到正确的数据。对于每一个线程都有一个专用的RSB,避免任何交叉弄脏数据。
拾取单元取得了每一个线程预测的下一个地址(通常情况下也就是正确的下一个地址),就到ITLB(指令旁路转换缓冲)和L1 I(一级指令缓存)去标注。ILTB由每个线程静态分配(平分),有128项缓存4KB的小页表,是4路联合方式的缓存;另外,每个线程还有7项用于缓存大页表文件(2MB/4MB),是全联合方式。L1 I是32KB,4路联合方式,由线程竞争共享。进入指令缓存后,每周期16Byte(128bit)的指令发送到预解码和拾取缓冲(pre-decode and fetch buffer)。然后,每周期6条指令从预解码和拾取缓冲发送到有18个项目数的指令队列(instruction queue)。在Core 2中,指令队列被用做循环缓存(Loop Stream Detector,LSD,循环流检测器),这样碰上小循环(指令数≤18)的时候,指令拾取单元就可以被关闭。而Nehalem的指令队列则只是作为指令被解码前的缓冲,因为它的循环缓存在流水线级数中,被放到了解码阶段的后面。
2、解码
当X86指令进入指令队列后,它们就等着被解码成微操作指令(uop),这是一种类似于RISC的指令。Core 2和Nehalem都有4个解码器,一个复杂解码器和3个简单解码器。简单解码器能够处理可以解码成一个uop的X86指令,现在绝大多数SSE指令都是这种。复杂解码器能够处理解码成1-4个uop的X86指令,而比这还要复杂的指令,则由微代码序列器(microcode sequencer)来处理。
Nehalem改进了宏操作融合(macro-op fusion)。Core 2可以在32bit模式下,把TEST/CMP(比较指令)和其后的Jcc(条件分支指令)给解码融合成一个微操作(uop):CMP+Jcc。这样就增加了解码带宽,并减少了微操作数量。而Nehalem的宏操作融合则包括了更多的条件分支指令:JL/JNGE, JGE/JNL, JLE/JNG, JG/JNLE。TEST/CMP和这些条件分支指令都将被解码成一个微操作:CMP+ Jcc。而且,Nehalem的宏操作融合可以是32bit和64bit模式。这是很重要的,因为现在大多数服务器都运行的是64bit操作系统,即使是桌面电脑也开始更多的欢迎64bit操作系统了。
一旦X86指令解码成微操作,就进入有28个项目数的微操作缓冲(uop buffer),Nehalem将其作为前面介绍到的LSD(Loop Stream Detector,循环流检测器)。如果一个循环不大于28个微操作,则Nehalem就可以将其缓存在LSD里,并发送到乱序执行引擎去执行,而关闭指令拾取单元和解码器。这样通过关闭解码器和使用更大的循环,就能够比Core 2的LSD节省更多的能耗。Nehalem的28项的微操作缓冲,能够保存相当于21-23条X86指令(根据在一些游戏中的测试情况得出的估计)。X86指令转换为微操作的比率取决于工作量的不同,不过总的来说,Nehalem具有比Core 2更大一些的LSD缓冲。
比较有趣的是,Nehalem的LSD缓冲看起来更象是指令追踪缓存(trace cache)。指令追踪缓存的目标是以动态程序的顺序来存储微操作,而不是象指令缓存里那样以静态编译顺序存储X86指令,因此可以从关键路径(critical path,指需要时间最长的路径)中去掉解码器和分支预测器,而使得被堵塞的地方可以立刻取得指令。P4的指令追踪缓存的问题在于它太脆弱了,当其命中失败时,就必须一个接一个地(重新)解码指令。通常指令缓存的命中率是在90%以上,而指令追踪缓存却远低于这个标准,很少时候超过80%,大多数时候是在50-60%。也就是说,在40-50%的时间里,P4都表现得象是一个单发射微处理器,而不能够完全利用上它的执行资源。而Nehalem的LSD缓冲取得了和指令追踪缓存几乎同样的目标,而且当它无法工作的时候(即当循环太大时),也没有什么要命的性能损失。
在LSD缓冲之后,解码步骤的最后一步是专用堆栈引擎(dedicated stack engine),除去所有被堆栈更改过的微操作。堆栈更改过的微操作都是被一个专用加法器给执行过了的,并写到前端的一个推测寄存器(speculative delta register)。推测寄存器偶尔会和重命名结构的寄存器(renamed architectural register)同步,而重命名结构寄存器中则保存有堆栈中的非推测值(non-speculative value)。当堆栈处理过的微操作都被清除之后,剩下的微操作就进入乱序执行引擎去被重命名、发送、分配和执行。
乱序引擎和执行部分
(Out-of-Order Engine and Execution Units)
Nehalem的乱序引擎显著的扩大了,除了性能原因,还有就是为了提供SMT,因为SMT需要资源共享。
和Core 2一样,Nehalem的寄存器重命名表(register alias table,RAT)指明每一个结构寄存器(architectural register)要么进入重排序缓冲(Re-Order Buffer,ROB),要么是进入撤销寄存器文件(Retirement Register File,RRF,或翻译为引退寄存器文件),并且保持有绝大多数最近的推测值状态(speculative state)。而RRF则保持有绝大多数最近的非推测状态(non-speculative state)。RAT可以每周期重命名4个微操作,给每一个微操作在ROB中一个目的地寄存器(destination register)。被重命名的指令就读取它们的源操作数并被发送到通用架构的保留站(unified Reservation Station,RS,可以被各种指令类型使用)。
Nehalem的ROB(重排序缓冲)从96项增加到128项,RS(保留站)从32项增加到36项,它们都由两个线程所共享,但是使用不同的策略。ROB是静态分配给2个线程,使得2个线程在指令流里都可以预测得一样远。而RS则是竞争共享,基于各线程的需求。这是因为许多时候一个线程可能会中止,从内存等待操作数,而使用到很少的RS项。这样就不如让另一个更活跃的线程尽可能多地使用RS项。在RS中的指令当其所有操作数都准备好时,就被分配到执行单元去。
Nehalem的执行单元与Core 2相比,基本没有大的改变,而且并不受SMT的影响,除了使用率更高之外。
缓存结构
几乎Nehalem的所有方面都是略为改进并增强,但存储子系统(memory subsystem,或翻译为内存子系统)却是非常激烈的大修理。
Nehalem可以同时运行的读取和存储量增加了50%,读取缓冲由32项增加到了48项,而存储缓冲由20项增加到了32项(增量还略多于50%)。增加的原因自然是为了让两个线程共享,这里采用的是静态分配,可能是由于关键路径的限制。
从读取缓冲和存储缓冲,存储操作就继续访问到缓存架构。Nehalem的缓存架构是完全革新了的。象P4一样,所有的缓存和数据TLB(Translation Lookaside Buffer,旁路转换缓冲,或叫页表缓冲)都是由2个线程动态共享(根据已经观察到的行为)。Nehalem的L1 D(一级数据缓存)保留了和Core 2一样的大小和联合度(associativity),但是延迟却从3个周期增加到了4个周期,以适应时间限制(timing constraint)。另外前面已经说到,每一个核心可以支持更多的未解决的命中失败(outstanding miss),最多到16个,可以利用更多的存储带宽。
而Nehalem剩下的缓存结构则和Core 2截然不同。Core 2的最后一级缓存是L2,由2个核心共享,这样可以减少一致性错误(coherency traffic),数量达到了24路联合的6MB(Penryn),延迟是14-15个周期(Conroe是14,Penryn是15)。而Nehalem有3级缓存,前两级相对较小,是每个核心私有的,而L3则非常大,由所有核心共享。
Nehalem的每个核心有一个私有的通用型L2,是8路联合的256KB,访问速度相当快。其使用延迟时间还没有完全披露,不过INTEL的工程师表明是小于12个周期的。Nehalem的L2相对于其L1D来说,既不是包含式(inclusive)也不是独占式(exclusive),就象Core 2一样,Nehalem可以在两个核心的私有缓存(L1D和L2)之间传递数据,尽管不能够达到全速。
Nehalem的16路联合、8MB的L3对于前两级来说,是完全包含式的,并且由4个核心共享。尽管INTEL并没有完全说明Nehalem的物理设计,但似乎L3缓存是单独使用电力,并运行在单独的频率上。这是从节省电力和可靠性这两个方面推断出来的,因为大的缓存更容易在低电压下产生软错误(soft error)。这样,L3使用延迟就取决于相对频率、核心的相差(phase alignment)、L3自身,还有访问L3的仲裁器的延迟。在最好的情况下,即操作相差和频率差距是整数倍的情况下,Nehalem的L3使用延迟是在30-40周期(根据INTEL工程师的说法)。
使用包含式缓存的好处是可以处理几乎所有的一致性流量问题(coherency traffic),而不需要打搅到每个独立核心的私有缓存。如果在L3中发生命中失败(cache miss),那么要访问的数据就肯定也不在任何一个L2和L1中,不需要侦听其它内核(而独占式缓存,则还要回头去检查其它内核)。
另一方面,Nehalem的L3对于缓存命中成功(cache hit),也扮演着侦听过滤器(snoop filter)的角色。独占式缓存命中成功时,不需要检查其它内核,而包含式缓存则一般需要检查其它内核。但是在Nehalem的L3中的每一个缓存行(cache line)里,有4 bit是用来做核心确认(core valid)的,表明是哪一个核心在它的私有缓存里具有这个行的数据备份。如果一个核心确认位被设置成0,则那个核心就不具有该行的数据备份。Nehalem使用的是MESIF缓存一致性协议(MESIF cache coherency protocol),如果两个以上核心的确认位都有效(设置成1),那么该缓存行就被确定是干净的(即未被修改的,任何一个内核的缓存行都不能够进入更改模式)。当L3缓存命中,而4个核心确认位都是0时,就不需要对其它内核做侦听;而只有1个位是有效时,则只需要侦听那一个核心。这两种技术的联合使用,使得L3可以尽可能的让每个核心避免数据一致性错误,这样就给出更多的实际带宽。
事实上,并非只有包含式缓存这一种解决之道。对于非包含式缓存来说,通过和最后一级缓存一起复制所有私有缓存的标志文件(tag file),并同时检查所有的最后一级缓存的访问标志和私有缓存的访问标志,也可以达到同样的性能好处,并避免数据一致性错误。而包含式缓存则是设计得必须复制数据,这就能够表明各级别之间大小的一定关系。Nehalem的每个核心有64KB L1D和256KB L2(有可能L1D的数据包含在L2中,也可能L1D的数据并没有包含在L2中。因为L2并非包含式),这就意味着在8MB的L3中,有1-1.25MB的数据是前两级缓存中也有的数据。这就是包含式缓存额外的开销。
Nehalem的缓存架构设计得也更容易支持非对齐(unaligned)的访问,有更快的非对齐缓存存取。INTEL前几代芯片一直是用两种类型指令来做16Byte(128bit)的SSE读取和存储,一种是其数据必须正好和缓存行(16B)对齐,比如MOVAPS/D、MOVDQA指令——(数据)必须刚好是16Byte,和缓存行对齐。另一种则可以是未对齐的,比如MOVUPS/D、MOVDQU指令,数据对齐与否是没有要求的。
在Nehalem之前,处理对齐的指令更有优势,而处理非对齐的指令则更慢、具有更低的数据吞吐量(即使其数据是在对齐的情况下),需要多个微操作。编译器也总是避免后一种指令,尽量避免非对齐的读取,象MOVSD+MOVHPD这样的2条连续指令就会更快一些。
而Nehalem则对非对齐指令进行了优化:在存取对齐数据的时候,非对齐指令和对齐指令具有一样的延迟和吞吐量。同时也提高了非对齐指令对于非对齐数据的访问速度。这样,不管是什么类型的SSE操作,都具有相同的延迟。另外Nehalem对在存取数据时跨越了64-Byte缓存行边界的情况也进行了优化,比起Core 2具有更低的延迟和更高的吞吐量。这样,编译器就不会再惧怕使用非对齐的指令了。
TLB,虚拟化性能
除了改变缓存架构,Nehalem还改变了TLB等级架构。TLB是用来缓存虚拟地址和物理地址映射关系的。Core 2有着非常有趣的TLB安排,L1 DTLB(INTEL有时也叫做micro-TLB)非常的小,并且只用来读取。它有16项小页表(4KB page)和16项大页表(2M/4M pages),每一个都是4路联合。L2 DTLB更大一些,可以读取和存储(当在L1 DTLB中读取失败时,就到L2 DTLB中来读取,并且L2 DTLB负责所有的存储),它有256项小页表和32项大页表,也都是4路联合。
Nehalem则建立起了真正意义上的两级TLB体系,可以动态分配给SMT的活跃线程状态(thread context)。Nehalem的L1 DTLB可以做所有的存储访问(可以读取和存储),它有64项小页表和32项大页表,也都是4路联合。而新的L2 TLB是通用型的(可以用于指令和数据),它只有512项小页表,也是4路联合。
Nehalem和Core 2的TLB的一个明显的差异是它们覆盖缓存的深度不同。Core 2(Penryn)有6MB L2,通过使用小页表(绝大多数的应用都不使用大页表),TLB可以转换2176KB的内存(地址),这样就覆盖了1/3的L2。而Nehalem的一个核心有576项小页表,整个CPU总共则是2304项,这样TLB就可以转换9216KB的内存,这已经超过8MB L3的容量了。
Nehalem的TLB项还通过使用虚拟处理器ID(Virtual Processor ID,VPID)而有所变化。每一个TLB项都缓存一个内存页的虚拟地址到物理地址的转换。而这个转换是特定于一个给定的进程或虚拟机(virtual machine,VM)。当处理器在虚拟客户端和主机之间切换时,INTEL过去的CPU都要往TLB里填写,以确保进程只能够访问到它们被允许访问的内存。而VPID则跟踪是哪一个VM的TLB项,这样在该VM退出后又重新进入时,TLB就不用填写也能够确保安全。如果一个进程试图访问不是它自己的地址转换,则就会直接在TLB中命中失败,而不会是到页表中去做非法访问。VPID通过降低虚拟机地址转换的开销(overhead)而有助于提升虚拟化性能。INTEL估计,Nehalem的一个来回的VM地址转换的延迟约是Conroe的40%,约比Penryn低1/3(即约是Penryn的66%)。
Nehalem另一个虚拟化方面的改变是扩展页表(Extended Page Tables,EPT),用来消除许多VM地址转换,即减少转换次数(而VPID的作用是降低VM地址转换的延迟)。通常的页表是用来匹配客户机的虚拟地址和客户机的物理地址,然而在一个虚拟化系统中,也有从客户机的物理地址到主机的物理地址的转换。INTEL早期的CPU(和AMD在Barcelona之前的CPU)将需要系统管理程序(hypervisor)来处理页面错误,而Nehalem则通过EPT,来消除了许多不必要的虚拟机退出。
Nehalem的模块化设计
以适应不同的市场需求。
模块化组件有:
1、核心数量
2、SMT功能
3、L3缓存容量
4、QPI连接数量
5、IMC数量
6、内存类型
7、内存通道数量
8、整合显卡
9、能耗和时钟频率
未来预定会发布的几种Nehalem有:
Gainestown,用于Xeon DP
Bloomfield,定位于高端桌面市场
这两种将于08年4季度上市。RWT认为可能Bloomfield将没有SMT。
2009年发布:
Havendale,桌面双核
Auburndale,移动双核
Clarksfield,移动四核
Beckton,用于Xeon MP
Lynnfield,桌面主流四核
Nehalem的电路级技术,可能得等到秋季IDF才会公布。AMD的4核,其电路设计就发生了非常大的改变,从原来的1个变成具有5个时钟分布网络(clock distribution network),有3个不同的电压层(voltage plane),并在不同时钟域(clock domain)之间使用动态FIFO。估计INTEL也将采用类似的手段来控制功耗和提升性能。现在比较有意思的问题是INTEL将采用何种动态时钟技术(dynamic clocking technique)来提升单个线程的性能。现在的Penryn已经可以动态提升一个核心的频率和电压,当另一个核心是空闲的时候。而这项技术显然对Nehalem是更有用的。
2Nehalem微架构
Nehalem微架构分为两个主要部分:计算内核与非计算内核
一. 计算内核的设计来源于之前的微架构,并对其进行了优化和加强,主要为以下几个方面:
(1) 支持超线程----第三代超线程技术,四核心时多达八个线程
(2) 支持虚拟化设备输入/输出 (VT-d)----在之前以虚拟化CPU为主的基础上增加设备输入/输出的虚拟化,能有效提高虚拟机的性能和效率。
(3) 内核加速模式(Turbo Mode)----内核运行动态加速。可以根据需要开启、关闭以及加速单个内核的运行。例如,在一个四核的Nehalem 微架构处理器中,如果一个任务只需要两个内核,可以关闭另外两个内核的运行,同时把工作的两个内核的运行主频提高。如果任务只需要一个内核,可以关闭其它三个内核,同时把工作的一个内核提高到更高的主频运行。这样动态的调整可以提高系统和CPU整体的能效比率。
(4) 新增的SSE 4.2指令集等等。
二. 非计算内核的设计改动令人瞩目,主要的有:
(1) Cache的设计----采用三级全内含式Cache设计,L1的设计和Core 微架构一样;L2采用超低延迟的设计,每个内核256KB;L3采用共享式设计,被片上所有内核共享。
(2) 集成了内存控制器(IMC)----从芯片组上移到CPU片上,支持多通道DDR3内存,内存读取的延迟大幅度减少,内存带宽大幅提升,最多可达三倍。
(3) QPI----"快速通道互联",取代前端总线(FSB)的一种点到点连接技术,20位宽的QPI连接其带宽可达惊人的每秒25.6GB,远非FSB可比。QPI最初能够发放异彩的是支持多个处理器的服务器平台,QPI可以用于多处理器之间的互联。
目前,基于Nehalem微架构的Bloomfield处理器(Bloomfield也是产品代码)已经正式命名为"酷睿 i7"。酷睿是品牌,"i7"是系列编号。酷睿这一名称现在和未来都将是英特尔公司PC处理器产品的旗舰品牌。
首款基于Nehalem微架构的处理器将是用于台式机的处理器酷睿 i7,支持的芯片组为x58。这款处理器有4个内核,计划在今年第四季度上市。用于服务器和笔记本电脑的Nehalem微架构处理器也会在将来陆续上市。
3Nehalem代号由来
熟悉英特尔公司的人大概都知道每个英特尔的产品或者具有代表性的技术在开发的时候都有一个产品代码或者项目代码。这些代码不会用于正式的产品上市,只会用于开发阶段的沟通。
英特尔产品上市时使用的正式品牌和产品名的确定要远远晚于产品的立项和开发阶段,产品的品牌和产品名涉及的方方面面太多,如法律方面的:商标注册,使用范围;人文方面的:用户接受度等等。
因此,为了沟通方面,就先使用代码沟通,英特尔公司把代码的选择权交给项目组或者项目的负责人,他们可以根据自己的喜好来给新产品和新技术取个代码。不过,命名也不是天马行空,有个前提,为了避免法律上潜在的风险,代码名字的选用应该是地图上可以找到的。
英特尔很多产品的开发部门都集中在加利福尼亚州(California)旧金山附近的硅谷以及俄勒冈州(Oregon)波特兰市周边,所以在这两个地方工作的英特尔项目组都会以工作地周围的地名,街道名,河流名,山名等等作为产品或者项目的代码,它们在地图上都可以找到。
当然,代码的选用不限于这两个州,项目的负责人也可以从自己家乡的地图或者其他地方地图上可以找到的名字来作为代码。在我印象中,中国团队负责的一些项目就用过像Pearl River(珠江),Yellow River(黄河), O'River(瓯江)等等,因为项目是区域性的,也只是在内部沟通使用,所以众多代码并不为公众知晓。
中国北京2008年1月8日,英特尔公司发布了首批基于英特尔迅驰处理器技术笔记本上的45纳米(nm)处理器,至此英特尔45纳米技术处理器家族全部产品已经悉数登场。简单说来,Nehalem还是基本建立在Core微架构(Core Microarchitecture)的骨架上,外加增添了SMT、3层缓存、TLB和分支预测的等级化、IMC、QPI和支持DDR3等技术。
目录
1Nehalem技术研究
·总述
·QPI总线技术
·IMC
·SMT
·前端部分
·乱序引擎和执行部分
·缓存结构
·TLB,虚拟化性能
·Nehalem的模块化设计
2Nehalem微架构
3Nehalem代号由来
1Nehalem技术研究
总述
下文中介绍的Nehalem的技术指标主要是以Nehalem-EP(Gainestown)为范例来介绍的,该核心将会用于Xeon DP,就是用于服务器的双路CPU。Nehalem是4核心、8线程、64bit、4超标量发射、乱序执行的CPU,有16级流水线、48bit虚拟寻址和40bit物理寻址。
比起从Pentium 4的NetBurst架构到Core 微架构的较大变化来说,从Core 微架到Nehalem架构的基本核心部分的变化则要小一些,因为Nehalem还是4指令宽度的解码/重命名/撤销。
Nehalem的核心部分比Core 微架构新增加的功能主要有以下几方面:
New SSE4.2Instructions (新增加SSE4.2指令)
Improved Lock Support (改进的锁定支持)
Additional Caching Hierarchy (新的缓存层次体系)
Deeper Buffers (更深的缓冲)
Improved Loop Streaming (改进的循环流)
Simultaneous Multi-Threading (同步多线程)
Faster Virtualization (更快的虚拟化)
Better Branch Prediction (更好的分支预测)
QPI总线技术
Nehalem使用的QPI总线是基于数据包传输(packet-based)、高带宽、低延迟的点到点互连技术(point to point interconnect),速度达到6.4GT/s(每秒可以传输6.4G次数据)。每一条连接(link)是20bit位宽的接口,使用高速的差分信号(differential signaling)和专用的时钟通道(dedicated clock lane),这些时钟通道具有失效备援(failover)。QPI数据包是80bit的长度,发送需要用4个周期。尽管数据包是80bit,但只有64bit是用于数据,其它的数据位则是用于流量控制、CRC和其它一些目的。这样,每条连接就一次传输16bit(2Byte)的数据,其余的位宽则是用于CRC。由于QPI总线可以双向传输,那么一条QPI总线连接理论最大值就可以达到25.6GB/s(2×2B×6.4GT/s)的数据传送。单向则是12.8GB/s。
对于不同市场的Nehalem,可以具有不同的QPI总线条数。比如桌面市场的CPU,具有1条或者半条QPI总线(半条可能是用10bit位宽或单向);DP服务器(双CPU插座)的CPU,每个具有2条QPI总线;而MP服务器(4个或8个CPU插座)的,则每个具有4条或更多的QPI总线。
IMC
Nehalem的IMC(integrated memory controller,整合内存控制器),可以支持3通道的DDR3内存,运行在1.33GT/s(DDR3-1333),这样总共的峰值带宽就可以达到32GB/s(3×64bit×1.33GT/s÷8)。不过还并不支持FB-DIMM,要Nehalem EX(Beckton)才有可能会支持FB-DIMM(Fully Buffered-DIMM,全缓冲内存模组)。每通道的内存都能够独立操作,控制器需要乱序执行来降低(掩盖)延迟。由于有了Core 2近4倍的内存带宽,Nehalem的每个核心支持最大10个未解决的数据缓存命中失败(outstanding data cache miss)和总共16个命中失败,而Core 2在运行中则只支持最大8个数据缓存的和总共14个的命中失败。
IMC能够很显著的降低内存延迟(尤其是对于采用FB-DIMM方案的系统)。下面的Nehalem与Harpertown,我不清楚是什么频率情况下的对比(来自于IDF上的表格,可能Nehalem是3.2GHz)。Nehalem的本地内存延迟大约是Harpertown的60%。Harpertown系统使用的是1.6GT/s的前端总线,所有内存都在一个位置,大约是略低于100ns(纳秒)的延迟,这样Nehalem的内存延迟就是约60ns。对于2个CPU插座的Nehalem来说,使用的是NUMA结构(Non Uniform Memory Access Achitecture,非均匀内存存取架构),远方内存的延迟则要高一些,因为这时对内存的请求和回应需要通过QPI总线,其延迟大约是Harpertown的95%。所以,即使是最糟糕的情况,延迟还是得到了降低。一个有意思的问题是,当使用4个CPU插座的Nehalem时,延迟是否将会被增大?因为这种系统很有可能会使用FB-DIMM,而这意味着将遭受延迟损失,不过远方内存的延迟还是将只会比本地内存慢个约30ns。
对于其它使用IMC和核心互连的多CPU系统(例如EV7、K8、K10),内存延迟也是非均匀的(NUMA)。为了优化性能,操作系统就必须知道延迟差异,并调度那些在同一个CPU上共享数据的进程。Windows Vista是Microsoft的第一个为NUMA进行优化的操作系统,而Linux等则已经很早就可以支持NUMA了。
Nehalem的远方/本地延迟比是约1.5倍。衡量K8的NUMA系数(也就是远方延迟除以本地延迟)在2 CPU系统时也差不多是1.5。而在4 CPU系统时,INTEL将具有优势,因为所有的内存要么都是本地(当QPI总线上没有hop时),或者所有内存都是远方(QPI总线上有一个hop时)。因为使用对角线连接,每个CPU都有QPI总线连接,那么远方内存最多就一跳(1个hop)。而现在的4插座的K8或K10系统,有的内存在HT总线上多达有2个hop。总之,具有更大的NUMA系数,就更需要软件考虑其所使用的内存的位置。作为参考,其中最早一个具备IMC和核心互连的EV7,在其64 CPU的系统中,NUMA系数为1.86-5.21(1-8个hop的情况)。
SMT
同步多线程(Simultaneous Multi-Threading,SMT)技术又重新回归到了Nehalem架构,这最早出现在130nm的P4上。对于打开了SMT的CPU来说,将会遭受到更多的命中失败,并需要使用更多的带宽。所以Nehalem比P4是更适合使用SMT的。另外,在移动和桌面领域的Nehalem有可能将不会支持SMT,它们也不需要3通道内存。
为什么Core 2没有使用SMT?很显然,它是可以做到的。SMT是在节省电力的基础上增加了性能,而且软件支持的基础建设也早就有了。有2个可能的原因:一是Core 2可能没有足够的内存带宽和CPU内部带宽来利用SMT获得优势。通常,SMT能够提升内存级并行(memory level parallelism,MLP),但是对于内存带宽已经成为瓶颈的系统则是个麻烦。而更有可能的原因则是SMT的设计、生效等是很麻烦的,而当初设计SMT是由INTEL的Hillsboro小组主持,而并非是Haifa小组(Core 2是由这个小组负责的)。这样Core 2不使用SMT就避免了冒险。
Nehalem的同步多线程(Simultaneous Multi-Threading,SMT)是2-way的,每核心可以同时执行2个线程。对于执行引擎来说,在多线程任务的情况下,就可以掩盖单个线程的延迟。SMT功能的好处是只需要消耗很小的核心面积代价,就可以在多任务的情况下提供显著的性能提升,比起完全再添加一个物理核心来说要划算得多。这个和以前P4的HT技术是一样的,但比较起来,Nehalem的优势是有更大的缓存和更大的内存带宽,这样就更能够有效的发挥。按照INTEL的说法,Nehalem的SMT可以在增加很少能耗的情况下,让性能提升20-30%。
对于SMT的各线程间所采用的资源共享策略有许多种:
1、复制型—— 线程都可以复制使用
寄存器状态
重命名RSB(重命名返回堆栈缓存)
大页表ITLB
2、静态分配型—— 一般由线程平分
各种主要的缓冲:读取、存储、重排序
小页表ITLB
3、竞争共享—— 由线程动态占有
保留站(RS)
缓存(Cache)
数据TLB(DTLB),L2 TLB
4、不受影响
执行单元
Nehalem同时也降低了同步原语(起始同步),比如LOCK prefix、XCHG和CMPXCHG等指令的延迟。同步原语在多线程编程中是必需的,而多线程的扩展性被同步所限制,通过降低延迟,可以提高现在多线程软件的性能。INTEL宣称,Nehalem的LOCK CMPXCHG指令(其作用是使整个流水线串行化)的延迟是P4的约20%,Core 2的约60%。尽管降低了延迟,但行为仍然和以前的CPU还是一样的,锁定指令(Lock)并不是管道化的,即使后面的操作可以被提前到锁定指令之前来执行。
前端部分
(指令拾取和解码)
1、指令拾取(包括分支预测)
在Nehalem的指令拾取单元(instruction fetch unit)中包含有相关指令指针(relative instruction point,RIP),每个线程状态(thread context)各有一个。在指令拾取单元中还包含有分支预测器,用来预测下一条将被拾取的指令的RIP。对于分支预测器的很多细节,INTEL并没有公布,但它们是适合于工作在SMT模式的。并且Nehalem也将继续使用上一代的那些特殊的分支预测器,比如循环检测器(loop detector),间接预测器(indirect predictor)等。
当分支预测器选定一条分支时,分支目标缓冲(branch target buffer,BTB)就负责预测目标地址。Nehalem使用了2级BTB结构。作为参考,K10使用了一个有2K 项(entry)的BTB用于直接分支,和一个有512项的间接分支目标阵列(indirect branch target array)。Nehalem的两级BTB设计,非常适用于有大量指令代码的任务,例如数据库、ERP和其它的商业应用,通过提高分支预测准确度而提升性能和能效。INTEL没有发布详细的内部结构。下面作出一些有依据的猜测。
有两种可能。一是两个BTB使用同样的预测算法,而一个存取更小一点的历史文件,包含最近时间内所使用的分支RIP和目标RIP。在这种情况下,它们的关系就象L1缓存和L2缓存一样(因为分支目标也具有相当好的地址相关性)。举个例子,比如L1 BTB有256-512项,而更大的L2 BTB则有2K-8K项。如果分支RIP在L1 BTB中没有找到,然后就到L2 BTB中去找,以作出目标预测。
另一种可能(RWT认为这种可能性比较小)则是两级BTB使用不同的预测算法和不同的历史文件。比如L1 BTB使用简单而快速的算法和相对较小的历史文件,而L2 BTB则使用更慢但更准确的算法,而且被配置成是具有优先权的预测器。如果L2 BTB不同意L1 BTB的预测,则它可以撤消(override)L1 BTB的预测,去除掉流水线中错误拾取的指令,而从新预测的RIP处重新拾取指令。这种结构可能性不大,因为它的能效比较低下。对于这种预测器架构,通常的情况是L1和L2 BTB都独立的得出正确的分支目标——这就意味着在大多数的时间里,L2 BTB都是在浪费能源。而L1 BTB错误,L2 BTB是正确的情况,只占非常小的比例。
不过在更早一点的ANANDTECH的文章中有提到认为是第二种方式:通常会遇到这样的情况,L1 BTB作出预测是基于分支的类型,但实际上它并没有历史数据,这样准确度就很低。而L2 BTB有更多的历史数据,就可以提高准确度,而且L2 BTB可以在执行过程中就纠正(L1 BTB所给出的)错误预测,而避免性能损失(这就正是override的情况)。
现在不清楚哪一种观点更正确一些。
Nehalem另一个提升分支目标预测的机制是对返回堆栈缓冲(return stack buffer,RSB)进行了重命名。当发生程序调用时,RSB就记录下地址,这样当结束调用返回时,就从该地址继续执行下去。但是当有很多程序递归调用时,RSB将会溢出,并且如果分支预测错误,那么也将会产生错误的返回地址。Nehalem通过重命名RSB,就避免了溢出。并且错误的分支预测也不会毁坏RSB,只要调用与返回地址是正确配对的,那么就可以从Nehalem的RSB中得到正确的数据。对于每一个线程都有一个专用的RSB,避免任何交叉弄脏数据。
拾取单元取得了每一个线程预测的下一个地址(通常情况下也就是正确的下一个地址),就到ITLB(指令旁路转换缓冲)和L1 I(一级指令缓存)去标注。ILTB由每个线程静态分配(平分),有128项缓存4KB的小页表,是4路联合方式的缓存;另外,每个线程还有7项用于缓存大页表文件(2MB/4MB),是全联合方式。L1 I是32KB,4路联合方式,由线程竞争共享。进入指令缓存后,每周期16Byte(128bit)的指令发送到预解码和拾取缓冲(pre-decode and fetch buffer)。然后,每周期6条指令从预解码和拾取缓冲发送到有18个项目数的指令队列(instruction queue)。在Core 2中,指令队列被用做循环缓存(Loop Stream Detector,LSD,循环流检测器),这样碰上小循环(指令数≤18)的时候,指令拾取单元就可以被关闭。而Nehalem的指令队列则只是作为指令被解码前的缓冲,因为它的循环缓存在流水线级数中,被放到了解码阶段的后面。
2、解码
当X86指令进入指令队列后,它们就等着被解码成微操作指令(uop),这是一种类似于RISC的指令。Core 2和Nehalem都有4个解码器,一个复杂解码器和3个简单解码器。简单解码器能够处理可以解码成一个uop的X86指令,现在绝大多数SSE指令都是这种。复杂解码器能够处理解码成1-4个uop的X86指令,而比这还要复杂的指令,则由微代码序列器(microcode sequencer)来处理。
Nehalem改进了宏操作融合(macro-op fusion)。Core 2可以在32bit模式下,把TEST/CMP(比较指令)和其后的Jcc(条件分支指令)给解码融合成一个微操作(uop):CMP+Jcc。这样就增加了解码带宽,并减少了微操作数量。而Nehalem的宏操作融合则包括了更多的条件分支指令:JL/JNGE, JGE/JNL, JLE/JNG, JG/JNLE。TEST/CMP和这些条件分支指令都将被解码成一个微操作:CMP+ Jcc。而且,Nehalem的宏操作融合可以是32bit和64bit模式。这是很重要的,因为现在大多数服务器都运行的是64bit操作系统,即使是桌面电脑也开始更多的欢迎64bit操作系统了。
一旦X86指令解码成微操作,就进入有28个项目数的微操作缓冲(uop buffer),Nehalem将其作为前面介绍到的LSD(Loop Stream Detector,循环流检测器)。如果一个循环不大于28个微操作,则Nehalem就可以将其缓存在LSD里,并发送到乱序执行引擎去执行,而关闭指令拾取单元和解码器。这样通过关闭解码器和使用更大的循环,就能够比Core 2的LSD节省更多的能耗。Nehalem的28项的微操作缓冲,能够保存相当于21-23条X86指令(根据在一些游戏中的测试情况得出的估计)。X86指令转换为微操作的比率取决于工作量的不同,不过总的来说,Nehalem具有比Core 2更大一些的LSD缓冲。
比较有趣的是,Nehalem的LSD缓冲看起来更象是指令追踪缓存(trace cache)。指令追踪缓存的目标是以动态程序的顺序来存储微操作,而不是象指令缓存里那样以静态编译顺序存储X86指令,因此可以从关键路径(critical path,指需要时间最长的路径)中去掉解码器和分支预测器,而使得被堵塞的地方可以立刻取得指令。P4的指令追踪缓存的问题在于它太脆弱了,当其命中失败时,就必须一个接一个地(重新)解码指令。通常指令缓存的命中率是在90%以上,而指令追踪缓存却远低于这个标准,很少时候超过80%,大多数时候是在50-60%。也就是说,在40-50%的时间里,P4都表现得象是一个单发射微处理器,而不能够完全利用上它的执行资源。而Nehalem的LSD缓冲取得了和指令追踪缓存几乎同样的目标,而且当它无法工作的时候(即当循环太大时),也没有什么要命的性能损失。
在LSD缓冲之后,解码步骤的最后一步是专用堆栈引擎(dedicated stack engine),除去所有被堆栈更改过的微操作。堆栈更改过的微操作都是被一个专用加法器给执行过了的,并写到前端的一个推测寄存器(speculative delta register)。推测寄存器偶尔会和重命名结构的寄存器(renamed architectural register)同步,而重命名结构寄存器中则保存有堆栈中的非推测值(non-speculative value)。当堆栈处理过的微操作都被清除之后,剩下的微操作就进入乱序执行引擎去被重命名、发送、分配和执行。
乱序引擎和执行部分
(Out-of-Order Engine and Execution Units)
Nehalem的乱序引擎显著的扩大了,除了性能原因,还有就是为了提供SMT,因为SMT需要资源共享。
和Core 2一样,Nehalem的寄存器重命名表(register alias table,RAT)指明每一个结构寄存器(architectural register)要么进入重排序缓冲(Re-Order Buffer,ROB),要么是进入撤销寄存器文件(Retirement Register File,RRF,或翻译为引退寄存器文件),并且保持有绝大多数最近的推测值状态(speculative state)。而RRF则保持有绝大多数最近的非推测状态(non-speculative state)。RAT可以每周期重命名4个微操作,给每一个微操作在ROB中一个目的地寄存器(destination register)。被重命名的指令就读取它们的源操作数并被发送到通用架构的保留站(unified Reservation Station,RS,可以被各种指令类型使用)。
Nehalem的ROB(重排序缓冲)从96项增加到128项,RS(保留站)从32项增加到36项,它们都由两个线程所共享,但是使用不同的策略。ROB是静态分配给2个线程,使得2个线程在指令流里都可以预测得一样远。而RS则是竞争共享,基于各线程的需求。这是因为许多时候一个线程可能会中止,从内存等待操作数,而使用到很少的RS项。这样就不如让另一个更活跃的线程尽可能多地使用RS项。在RS中的指令当其所有操作数都准备好时,就被分配到执行单元去。
Nehalem的执行单元与Core 2相比,基本没有大的改变,而且并不受SMT的影响,除了使用率更高之外。
缓存结构
几乎Nehalem的所有方面都是略为改进并增强,但存储子系统(memory subsystem,或翻译为内存子系统)却是非常激烈的大修理。
Nehalem可以同时运行的读取和存储量增加了50%,读取缓冲由32项增加到了48项,而存储缓冲由20项增加到了32项(增量还略多于50%)。增加的原因自然是为了让两个线程共享,这里采用的是静态分配,可能是由于关键路径的限制。
从读取缓冲和存储缓冲,存储操作就继续访问到缓存架构。Nehalem的缓存架构是完全革新了的。象P4一样,所有的缓存和数据TLB(Translation Lookaside Buffer,旁路转换缓冲,或叫页表缓冲)都是由2个线程动态共享(根据已经观察到的行为)。Nehalem的L1 D(一级数据缓存)保留了和Core 2一样的大小和联合度(associativity),但是延迟却从3个周期增加到了4个周期,以适应时间限制(timing constraint)。另外前面已经说到,每一个核心可以支持更多的未解决的命中失败(outstanding miss),最多到16个,可以利用更多的存储带宽。
而Nehalem剩下的缓存结构则和Core 2截然不同。Core 2的最后一级缓存是L2,由2个核心共享,这样可以减少一致性错误(coherency traffic),数量达到了24路联合的6MB(Penryn),延迟是14-15个周期(Conroe是14,Penryn是15)。而Nehalem有3级缓存,前两级相对较小,是每个核心私有的,而L3则非常大,由所有核心共享。
Nehalem的每个核心有一个私有的通用型L2,是8路联合的256KB,访问速度相当快。其使用延迟时间还没有完全披露,不过INTEL的工程师表明是小于12个周期的。Nehalem的L2相对于其L1D来说,既不是包含式(inclusive)也不是独占式(exclusive),就象Core 2一样,Nehalem可以在两个核心的私有缓存(L1D和L2)之间传递数据,尽管不能够达到全速。
Nehalem的16路联合、8MB的L3对于前两级来说,是完全包含式的,并且由4个核心共享。尽管INTEL并没有完全说明Nehalem的物理设计,但似乎L3缓存是单独使用电力,并运行在单独的频率上。这是从节省电力和可靠性这两个方面推断出来的,因为大的缓存更容易在低电压下产生软错误(soft error)。这样,L3使用延迟就取决于相对频率、核心的相差(phase alignment)、L3自身,还有访问L3的仲裁器的延迟。在最好的情况下,即操作相差和频率差距是整数倍的情况下,Nehalem的L3使用延迟是在30-40周期(根据INTEL工程师的说法)。
使用包含式缓存的好处是可以处理几乎所有的一致性流量问题(coherency traffic),而不需要打搅到每个独立核心的私有缓存。如果在L3中发生命中失败(cache miss),那么要访问的数据就肯定也不在任何一个L2和L1中,不需要侦听其它内核(而独占式缓存,则还要回头去检查其它内核)。
另一方面,Nehalem的L3对于缓存命中成功(cache hit),也扮演着侦听过滤器(snoop filter)的角色。独占式缓存命中成功时,不需要检查其它内核,而包含式缓存则一般需要检查其它内核。但是在Nehalem的L3中的每一个缓存行(cache line)里,有4 bit是用来做核心确认(core valid)的,表明是哪一个核心在它的私有缓存里具有这个行的数据备份。如果一个核心确认位被设置成0,则那个核心就不具有该行的数据备份。Nehalem使用的是MESIF缓存一致性协议(MESIF cache coherency protocol),如果两个以上核心的确认位都有效(设置成1),那么该缓存行就被确定是干净的(即未被修改的,任何一个内核的缓存行都不能够进入更改模式)。当L3缓存命中,而4个核心确认位都是0时,就不需要对其它内核做侦听;而只有1个位是有效时,则只需要侦听那一个核心。这两种技术的联合使用,使得L3可以尽可能的让每个核心避免数据一致性错误,这样就给出更多的实际带宽。
事实上,并非只有包含式缓存这一种解决之道。对于非包含式缓存来说,通过和最后一级缓存一起复制所有私有缓存的标志文件(tag file),并同时检查所有的最后一级缓存的访问标志和私有缓存的访问标志,也可以达到同样的性能好处,并避免数据一致性错误。而包含式缓存则是设计得必须复制数据,这就能够表明各级别之间大小的一定关系。Nehalem的每个核心有64KB L1D和256KB L2(有可能L1D的数据包含在L2中,也可能L1D的数据并没有包含在L2中。因为L2并非包含式),这就意味着在8MB的L3中,有1-1.25MB的数据是前两级缓存中也有的数据。这就是包含式缓存额外的开销。
Nehalem的缓存架构设计得也更容易支持非对齐(unaligned)的访问,有更快的非对齐缓存存取。INTEL前几代芯片一直是用两种类型指令来做16Byte(128bit)的SSE读取和存储,一种是其数据必须正好和缓存行(16B)对齐,比如MOVAPS/D、MOVDQA指令——(数据)必须刚好是16Byte,和缓存行对齐。另一种则可以是未对齐的,比如MOVUPS/D、MOVDQU指令,数据对齐与否是没有要求的。
在Nehalem之前,处理对齐的指令更有优势,而处理非对齐的指令则更慢、具有更低的数据吞吐量(即使其数据是在对齐的情况下),需要多个微操作。编译器也总是避免后一种指令,尽量避免非对齐的读取,象MOVSD+MOVHPD这样的2条连续指令就会更快一些。
而Nehalem则对非对齐指令进行了优化:在存取对齐数据的时候,非对齐指令和对齐指令具有一样的延迟和吞吐量。同时也提高了非对齐指令对于非对齐数据的访问速度。这样,不管是什么类型的SSE操作,都具有相同的延迟。另外Nehalem对在存取数据时跨越了64-Byte缓存行边界的情况也进行了优化,比起Core 2具有更低的延迟和更高的吞吐量。这样,编译器就不会再惧怕使用非对齐的指令了。
TLB,虚拟化性能
除了改变缓存架构,Nehalem还改变了TLB等级架构。TLB是用来缓存虚拟地址和物理地址映射关系的。Core 2有着非常有趣的TLB安排,L1 DTLB(INTEL有时也叫做micro-TLB)非常的小,并且只用来读取。它有16项小页表(4KB page)和16项大页表(2M/4M pages),每一个都是4路联合。L2 DTLB更大一些,可以读取和存储(当在L1 DTLB中读取失败时,就到L2 DTLB中来读取,并且L2 DTLB负责所有的存储),它有256项小页表和32项大页表,也都是4路联合。
Nehalem则建立起了真正意义上的两级TLB体系,可以动态分配给SMT的活跃线程状态(thread context)。Nehalem的L1 DTLB可以做所有的存储访问(可以读取和存储),它有64项小页表和32项大页表,也都是4路联合。而新的L2 TLB是通用型的(可以用于指令和数据),它只有512项小页表,也是4路联合。
Nehalem和Core 2的TLB的一个明显的差异是它们覆盖缓存的深度不同。Core 2(Penryn)有6MB L2,通过使用小页表(绝大多数的应用都不使用大页表),TLB可以转换2176KB的内存(地址),这样就覆盖了1/3的L2。而Nehalem的一个核心有576项小页表,整个CPU总共则是2304项,这样TLB就可以转换9216KB的内存,这已经超过8MB L3的容量了。
Nehalem的TLB项还通过使用虚拟处理器ID(Virtual Processor ID,VPID)而有所变化。每一个TLB项都缓存一个内存页的虚拟地址到物理地址的转换。而这个转换是特定于一个给定的进程或虚拟机(virtual machine,VM)。当处理器在虚拟客户端和主机之间切换时,INTEL过去的CPU都要往TLB里填写,以确保进程只能够访问到它们被允许访问的内存。而VPID则跟踪是哪一个VM的TLB项,这样在该VM退出后又重新进入时,TLB就不用填写也能够确保安全。如果一个进程试图访问不是它自己的地址转换,则就会直接在TLB中命中失败,而不会是到页表中去做非法访问。VPID通过降低虚拟机地址转换的开销(overhead)而有助于提升虚拟化性能。INTEL估计,Nehalem的一个来回的VM地址转换的延迟约是Conroe的40%,约比Penryn低1/3(即约是Penryn的66%)。
Nehalem另一个虚拟化方面的改变是扩展页表(Extended Page Tables,EPT),用来消除许多VM地址转换,即减少转换次数(而VPID的作用是降低VM地址转换的延迟)。通常的页表是用来匹配客户机的虚拟地址和客户机的物理地址,然而在一个虚拟化系统中,也有从客户机的物理地址到主机的物理地址的转换。INTEL早期的CPU(和AMD在Barcelona之前的CPU)将需要系统管理程序(hypervisor)来处理页面错误,而Nehalem则通过EPT,来消除了许多不必要的虚拟机退出。
Nehalem的模块化设计
以适应不同的市场需求。
模块化组件有:
1、核心数量
2、SMT功能
3、L3缓存容量
4、QPI连接数量
5、IMC数量
6、内存类型
7、内存通道数量
8、整合显卡
9、能耗和时钟频率
未来预定会发布的几种Nehalem有:
Gainestown,用于Xeon DP
Bloomfield,定位于高端桌面市场
这两种将于08年4季度上市。RWT认为可能Bloomfield将没有SMT。
2009年发布:
Havendale,桌面双核
Auburndale,移动双核
Clarksfield,移动四核
Beckton,用于Xeon MP
Lynnfield,桌面主流四核
Nehalem的电路级技术,可能得等到秋季IDF才会公布。AMD的4核,其电路设计就发生了非常大的改变,从原来的1个变成具有5个时钟分布网络(clock distribution network),有3个不同的电压层(voltage plane),并在不同时钟域(clock domain)之间使用动态FIFO。估计INTEL也将采用类似的手段来控制功耗和提升性能。现在比较有意思的问题是INTEL将采用何种动态时钟技术(dynamic clocking technique)来提升单个线程的性能。现在的Penryn已经可以动态提升一个核心的频率和电压,当另一个核心是空闲的时候。而这项技术显然对Nehalem是更有用的。
2Nehalem微架构
Nehalem微架构分为两个主要部分:计算内核与非计算内核
一. 计算内核的设计来源于之前的微架构,并对其进行了优化和加强,主要为以下几个方面:
(1) 支持超线程----第三代超线程技术,四核心时多达八个线程
(2) 支持虚拟化设备输入/输出 (VT-d)----在之前以虚拟化CPU为主的基础上增加设备输入/输出的虚拟化,能有效提高虚拟机的性能和效率。
(3) 内核加速模式(Turbo Mode)----内核运行动态加速。可以根据需要开启、关闭以及加速单个内核的运行。例如,在一个四核的Nehalem 微架构处理器中,如果一个任务只需要两个内核,可以关闭另外两个内核的运行,同时把工作的两个内核的运行主频提高。如果任务只需要一个内核,可以关闭其它三个内核,同时把工作的一个内核提高到更高的主频运行。这样动态的调整可以提高系统和CPU整体的能效比率。
(4) 新增的SSE 4.2指令集等等。
二. 非计算内核的设计改动令人瞩目,主要的有:
(1) Cache的设计----采用三级全内含式Cache设计,L1的设计和Core 微架构一样;L2采用超低延迟的设计,每个内核256KB;L3采用共享式设计,被片上所有内核共享。
(2) 集成了内存控制器(IMC)----从芯片组上移到CPU片上,支持多通道DDR3内存,内存读取的延迟大幅度减少,内存带宽大幅提升,最多可达三倍。
(3) QPI----"快速通道互联",取代前端总线(FSB)的一种点到点连接技术,20位宽的QPI连接其带宽可达惊人的每秒25.6GB,远非FSB可比。QPI最初能够发放异彩的是支持多个处理器的服务器平台,QPI可以用于多处理器之间的互联。
目前,基于Nehalem微架构的Bloomfield处理器(Bloomfield也是产品代码)已经正式命名为"酷睿 i7"。酷睿是品牌,"i7"是系列编号。酷睿这一名称现在和未来都将是英特尔公司PC处理器产品的旗舰品牌。
首款基于Nehalem微架构的处理器将是用于台式机的处理器酷睿 i7,支持的芯片组为x58。这款处理器有4个内核,计划在今年第四季度上市。用于服务器和笔记本电脑的Nehalem微架构处理器也会在将来陆续上市。
3Nehalem代号由来
熟悉英特尔公司的人大概都知道每个英特尔的产品或者具有代表性的技术在开发的时候都有一个产品代码或者项目代码。这些代码不会用于正式的产品上市,只会用于开发阶段的沟通。
英特尔产品上市时使用的正式品牌和产品名的确定要远远晚于产品的立项和开发阶段,产品的品牌和产品名涉及的方方面面太多,如法律方面的:商标注册,使用范围;人文方面的:用户接受度等等。
因此,为了沟通方面,就先使用代码沟通,英特尔公司把代码的选择权交给项目组或者项目的负责人,他们可以根据自己的喜好来给新产品和新技术取个代码。不过,命名也不是天马行空,有个前提,为了避免法律上潜在的风险,代码名字的选用应该是地图上可以找到的。
英特尔很多产品的开发部门都集中在加利福尼亚州(California)旧金山附近的硅谷以及俄勒冈州(Oregon)波特兰市周边,所以在这两个地方工作的英特尔项目组都会以工作地周围的地名,街道名,河流名,山名等等作为产品或者项目的代码,它们在地图上都可以找到。
当然,代码的选用不限于这两个州,项目的负责人也可以从自己家乡的地图或者其他地方地图上可以找到的名字来作为代码。在我印象中,中国团队负责的一些项目就用过像Pearl River(珠江),Yellow River(黄河), O'River(瓯江)等等,因为项目是区域性的,也只是在内部沟通使用,所以众多代码并不为公众知晓。