深入理解Nehalem(Inside Nehalem)

原文来自:http://www.realworldtech.com/
原文作者:David Kanter
发布时间: 04-02-2008

一、引言

   近10年,Intel和AMD的X86CPU架构差别越来越大。Intel的Pentium4采用更加依赖程序员编写合适代买的高时钟频率的设计理念,而AMD则在K7的基础上大胆创新,集成存储控制器,细化了微架构的设计。沿着各自的发展道路,Intel终于发现高主频设计对于便携系统是一个噩梦,于是他们又重新启用了更早一点的Pentium Pro(P6)架构,将其改进后作为面向便携机的新架构,该架构最终出现了65nm的Core Duo的设计。近两年,对Intel来说仿佛是进入到一个复兴的时代,他们用高效的基于Core 2 Duo架构的处理器替代了最后残存的Pentium 4处理器。

    从很多方面来看,Core 2是移动版本CPU的衍生,比如关注于双核实现或简单的时钟分布。实际上Core 2是一个从桌面系统到服务器系统均能得到卓越效果的均衡设计,今后会更加关注在移动领域。这表现出英特尔的Haifa设计团队的实力,这个团队自从Timna项目开始就一直在做移动版本的设计,只是最近才开始进行服务器版本的设计。相比较而言,英特尔的Hillsboro设计团队长期关注P6架构的服务器版本设计。

    目前,几乎英特尔所有的产品都是基于Core 2微架构,采用已经很老的前端总线作为系统连接电路。而实际上,这正是英特尔和AMD所提供的技术中最大的不同之处。不像Core 2,AMD的Barcelona(巴塞罗纳)首先瞄准的是服务器市场,他们最重要的特点是集成存储控制器、HyperTransport总线和在一个芯片中集成4个核。不幸的是,Barcelona并没能得到预想的结果,它比期望的发布时间晚,而且频率偏低,还遭遇了快表TLB的BUG。在Barcelona最新的B3步进的版本中修补了这个严重的问题(TLB bug),预期频率会有所提升,这将使Barcelona的性能能够达到与当前基于Core 2设计的英特尔处理器相竞争的境地。

    在本届IDF(2008年春季英特尔开发者论坛)上,英特尔发布了第二代45nm微架构Nehalem的细节和他们研发线下一步的发展计划。与前代不同,Nehalem不仅明确是为所有不同的产品线来设计的,还为从移动到多处理器服务器的所有产品而做优化。这意味着将比Core 2更据灵活性。Nehalem在各个方面都几乎做了改进,最主要的是系统结构和存储方面。本文将介绍英特尔Nehalem这个原生四核、8线程、提供48位虚拟地址空间和40位物理地址空间,使用了high-K门电介质金属门材料的高性能处理器的流水线和架构的细节。

二、Core、Cache与互连

   英特尔目前基于前端总线的架构是很适合笔记本和桌面系统的,但是如果对于现代服务器和工作站系统就不免差强人意。笔记本系统使用1到2个核,更关注成本和功耗,对单任务需要更低的延迟。桌面系统的需求类似,不过更关注成本而对功耗的关注要少一些,但桌面系统在执行离散图形解析问题时必须能处理更高的带宽。相反,服务器可以用无数的核,需要很大的带宽和在保持功耗在一个合理范围内的情况下同时执行多个不同任务时反应时间较短。对于MP服务器,高端应用,可靠性和有效性成为关键性问题。

   Nehalem的一个主要目的是定义一个灵活的结构以为所有不同的市场进行优化,一个主要的改变是采用了一种能够很好的适应所有竞争目的和要求的系统架构。Nehalem体现了英特尔系统基本结构的一次完整的改进,最重要的改变来自于最近几年发展起来的P6架构的指令。图1显示了Nehalem、Barcelona和Harpertown的系统架构。

图1 Nehalem、Barcelona和Harpertown的系统架构。

   Nehalem完整地集成了4个核,并带有一个包含与共享3级Cache。一个中央队列在Nehalem的四个核与非核区域之间充当交叉开关和仲裁器。在Nehalem中还包含了L3 Cache,集成存储控制器和QPI链接。从性能的角度看, 包含式L3 Cache是一个理想的结构因为他能在片上事务中保持Cache一致性。片上的通信会在低延迟和低功耗上受益。另外,最后一级Canche共享,会降低重复。AMD在65nm的Barcelona中用283mm2的芯片面积实现这一转换。英特尔45nm的Harpertown实际上是将两个双核封装在一个芯片中,这样的好处是芯片面积小,捆绑构造更为自由。根据工作量,在Harpertown的两个Cache中可能会存在某些数据位的重复。(当然至少指令的工作集会缓存)。通过消除这样的重复,一个统一的cache可以变得很小而缓存的数据量却是相同的。

   虽然集成4核具有性能上的优势,但正如英特尔自己在此前指出的这种集成是具有代价的。更大的芯片尺寸意味着更低的每瓦特成品率,这会是制造处理器的早期所拥有的问题。更大的集成能降低顶层设备数而增加点缺陷(一种晶体的原子线性排列的不对称,它只影响一个或两个栅格)的脆弱性,因为一个设备的运行速度取决于运行最慢的部件。

   Nehalem替换了前端总线,并增加了一个集成的存储控制器和一个片上专用的处理期间的连接。概要的说,QPI是一个基于包的,高带宽低延迟的点到点连接,其传输速率在45nm工艺中达到了6.4GT/s(65nm工艺中是4.8GT/s)。每个全带宽的连接被设计成具有20位数据宽度的,使用高速差分信号和专用时钟通道的接口。QPI包有80位,只有64位是有效数据,剩下的是流控制,CRC和其他的东西。这意味着在每个方向上每个连接每次传输16位(2个字节)的数据,传输率是12.8GB/s,剩下的位用作CRC。由于连接是双向的,所以实际上每个全带宽连接的速率是25.6GB/s。Nehalem在实现的时候会更具市场和系统的适应性,调整QPI连接的数量。客户端系统使用的连接最少,大概是1条或者半条,DP服务器有两条连接,而MP服务器就可以有3条半或者4条连接。

三、存储控制

   Nehalem的集成存储控制器支持3通道DDR3内存运行于1.33GT/s的速率下,峰值带宽达到32GB/s(3×64bit×1.33GT/s÷8)。存储控制器支持registered的和unregistered型的DDR3,但是目前还不主要支持FB-DIMM(Fully Buffered-DIMM,全缓冲内存模组)。可能要到Nehalem EX或者Beckton才会支持FB-DIMM。每个存储通道能够独立操作,控制器需要乱序来减小延迟。为了充分发挥4倍增长的存储带宽的优势,每个核支持最大10个数据的Cache访问失败,总共可以是16个数据的Cache访问失败。相比较而言,Core 2只有每核8个,总共16个未处理完数据的Cache访问失败。

   集成存储控制器充分改善了存储延迟(特别是针对基于FB-DIMM的解决方案)。Nehalem本地存储延迟大约是使用1.6GT/s前端总线的Harperton系统的60%。后者的延迟大约是100ns内,因此Nehalem的本地内存延迟大约是60ns。对于Nehalem双CPU的系统,远程延迟会高一些,因为存储请求和回应都要经过一个QPI连接。远程延迟大约是Harpertown系统的95%,所以,即使在最坏的情况下,延迟都有所改观。一个有趣的问题是如果是Nehalem 4CPU系统,延迟将会是什么样的。看起来这些系统将会使用FB-DIMM,这意味着延迟的问题可能会恶化,不过远程存储访问的延迟将还是只会比本地存储访问稍慢30ns。

   就像其他使用集成存储控制器和片内互连结构的系统(EV7,K8,Barcelona等)一样,内存延迟也是非均匀的(NUMA)。为了优化性能,操作系统必须知道延迟上的差异,并将共享数据的进程调度到一个CPU中。Linux等操作系统老早就开始支持NUMA的调度,而Windows Vista是微软的第一个为NUMA进行优化的客户端操作系统。

   Nehalem的远程延迟大约是本地延迟的1.5倍。考察一下K8的情况表明,在双CPU系统中远程/本地延迟比也是大约1.5。但是如果是4 CPU系统,英特尔将更有优势,因为所有的存储要么都在本地(在QPI上没有转发(hop)),要么就在远程(QPI上只有一次转发,因为QPI是点对点的)。而现在的4 CPU的K8或者Barcelona系统需要两次转发。通常,NUMA远程/本地延迟比越大,对软件来说注意尽可能用局部数据就越发重要。作为参考,第一个使用集成存储控制器和片内连接的64位CPU(EV7)的NUMA远程/本地延迟比是1.8~5.21 (1~8个转发)。

四、SSE4.2和SMT

   Nehalem还包括一个指令集扩展,因为它们会影响到微代码,所以这种指令扩展贯穿整个核流水线。Nehalem包含的SSE4.2指令包括了传处理的指令,一个CRC指令和一个popcount。串指令全是微代码,其对性能改进有限。CRC指令被用于计算校验和,这对存储和网络是有用的。当然,整体上说,加速是比较小的,因为英特尔给的例子只是处理很紧密的内循环。

   Nehalem在系统结构上最后一个主要的改变是重新使用了同时多线程技术SMT,该技术最早是在EV8中讨论的,但最早的使用是在130nm的P4中。SMT并不是严格意义上的系统级改变,而是一个核的改变,而牵涉到Nehalem的方方面面。另外,SMT毕竟还是牵涉到系统结构。给两个微处理器,一个有SMT功能一个没有,一个有SMT技术的CPU更会引起存储器访问的Cache命中失败,并且需要更多的带宽。和P4相比,Nehalem更像是为了SMT技术的需求而设计的。不过也许桌面和便携系统的Nehalme处理器不用SMT技术,也用不到全部的三个存储器通道。

   一个有趣的问题是为什么Core 2没有使用SMT技术。显然,它应该和Nehalem一样是可以做到的。SMT技术能够在不高的功耗下提高性能,而且软件也已经支持这个技术。Core 2没有支持SMT的原因大概有2。首先,Core 2可能没有足够的存储和处理器内联带宽来从SMT技术中获得受益。通常,SMT能够充分提高系统的存储级并行(MLP),但如果系统本来就存在存储带宽瓶颈的话,SMT技术就会有问题。

   一个更主要的原因是SMT处理器的设计看起来简单,实际上却是非常困难的。根据推测,180nm的P4 Willamette的时候就已经具备了实现SMT的必要电路,但由于SMT技术验证比较困难,所以并没能使能该技术,直到130nm的Northwood的后期才真正实现。更重要的,几乎所有的设计、验证和调试SMT处理器的技术是来源于英特尔的Hillsboro设计团队而不是Haifa团队。因此决定不在Core 2中实现SMT以避免冒险。

五、前端:取指阶段

  Nehalem的取指阶段确实做了大的修改,尽管在图2中没有将细节表现出来。在下图的取指单元包含相关指令指针(RIP),每个线程环境一个备份。

图2 前端微架构比较

   取指单元还包含分支预测,用以预测要取的下条指令的RIP。Nehalem分支预测的细节没有在图中示出,部分原因是其中有些细节还不太清楚。英特尔只是简单的说它们使用了“best in class”分支预测技术,它们的分支预测适合SMT技术。英特尔已经证实,Nehalem继续使用前代中使用的所有特别的预测器,比如循环预测器,间接预测器等。

   一旦分支预测器确定有分支出现,分支目标缓冲器(BTB)负责预测目标地址。Nehalem使用两级BTB来扩展前代分支预测器。作为参考,Barcelona使用一个2K项的BTB来直接预测,用一个512项间接预测目标阵列。

   Nehalem的两级BTB设计通过改进分支预测精确度来增加性能和降低功耗。这种改进非常适合具有大量指令的应用领域,比如数据库,ERP和其他商业应用。英特尔没有精确地描述内部方案,但是可以根据实际和经验来进行猜测。

   在高级层面,有两个可能性。第一个可能性是这两级BTBs可以用相同的预测算法,但是一个存取稍小的历史文件,该文件包含最近使用的分支RIP和目标RIP。如果是这样的话,那么这两个BTB之间的关系就如同L1 Cache和L2 Cache之间的关系(记住分支目标有很好的局部性)。比如第一级BTB能够有256~512项,而大一点的2级BTB能够有2~8K项。如果一个分支RIP不在第一级BTB中,那么他会检查2级BTB来做目标预测。这样做的好处是可以只用较低的功耗,除非指令量很大(例如不能够在L1 BTB中放下)的时候除外。然而,用较小的分支预测比用L2 BTB显然要更节省功耗。

   第二个可能性是第一级和第二级BTB使用不同的预测算法和不同的历史文件。比如,第一级BTB可能使用一个很简单而快速的算法,并配以相对小的历史记录表,而第2级BTB使用一个相对较慢但较精确的算法作为修正算法。如果第二级预测和第一级预测不一致,则第二级预测将修正第一级的错误预测,并将流水线中错误取出的指令清空,按照新的预测RIP取指。英特尔应该不太可能使用这种方法,因为它的能效比较低。这种两级修正式预测器通常是L1 BTB和L2 BTB独立提出正确的分支目标,这就意味着大多数情况下,L2 BTB只是在浪费能量。只有当L1 BTB预测错误,而L2 BTB预测成功的情况下修正预测才有用,而这种情况发生的几率很小。我们不相信英特尔会采用这种方法,这里介绍它只是因为有这种可能的方案而已。

   Nehalem另一个分支目标预测机制的改进是返回栈缓冲(RSB)。当一个函数被调用,RSB记录地址,当这个函数返回的时候,它将直接从刚才保留的地方取出地址。如果太多的函数嵌套调用,RSB也会溢出,而如果预测器推测的路径错误,RSB也会给出错误的返回地址。Nehalem采用重命名RSB来避免返回栈溢出,并保证大多数错误的预测不会影像到RSB。每一个线程都有自己的专用RSB,这可以避免交叉干扰。

   取指单元为每个线程取出预测的地址(通常是下一条指令)然后将它们索引进ITLB(指令快表)和L1 指令cache。 ITLB为两个线程静态分配,它用128项缓存4KB页,这些页是4路相联。另外每个线程有7个全相连的用于缓存大页面(2M/4M)的项来共享小页面项。指令Cache有32KB,采用4路相联,在线程间被竞争共享。每次取到Cache中的指令会将指令的16字节(128位)放进预译码单元和取指缓冲。然后6条指令从缓冲发送到有18项的指令队列中。在Core 2中,指令队列被用作循环缓冲(循环流检测器或者LSD,Loop Stream Detector),所以指令预取单元可以在遇到小循环(指令数≤18)的时候暂时关闭。Nehalem的指令队列在指令译码前只做缓冲,因为循环cache被放到了指令流水的译码阶段。

六、前端:译码阶段

   一旦x86宏指令被取到了指令队列,他们将准备译码成微代码,这些微代码是英特尔微架构支持的内部类似RISC的指令。Core 2和Nehalem都有四个译码器,一个复杂的三个简单的。一个简单译码器能处理任何X86指令并将其译码到一个微代码,现在这样的指令还包括很多SSE指令。复杂译码器能译码指令到1~4个微代码,微代码序列发生器处理任何更复杂的指令。

   Nehalem改进了前代出现的宏指令融合技术。在32位模式,Core 2能够译码将比较(CMP)或测试(TEST)与条件分支(Jcc)译码成一个微代码CMP+JCC。这增加了Core 2的译码带宽,降低了微代码量,提高了机器的效率。在Nehalem中,宏指令融合包含的分支条件更多,包括了JL/JNGE, JGE/JNL, JLE/JNG, JG/JNLE,这些指令的任何一个在上述情况下都会被编译成单独的CMP+JMP微代码。更好的消息是,Nehalem的宏指令融合技术在32位和64位下都是可用的。这一点很重要,因为大多数服务器和工作站都是工作在64位操作系统下的。即使是现代桌面系统也逐渐开始准备使用64位操作系统。除了融合x86宏指令外,译码逻辑还融合微代码,这是一个在Pentium M中就使用的技术,(它将译码自同一个x86指令的几个微代码融合成更少的微代码-译者注)。

   一旦x86指令被译码到微代码,他们被装进一个28项的微代码缓冲中。前面提到过,Core 2在取指单元的一个18项指令队列中有一个循环流检测器(LSD)作为Cache。Nehalem将这一概念加以改进,将LSD移到了流水线的更下端的译码阶段中的一个新的28项微代码缓冲中。

   如果一个循环小于28条微代码,那么Nehalem能够将其缓存到LSD中并发射到乱序引擎中而不需要用到取指单元或译码单元。这将比Core 2用LSD更省能耗,因为它避免了译码并且更多的循环能够被缓存。从一些游戏程序的测量情况看,Nehalem28项微代码缓冲大约能容下21~23条x86宏指令。宏指令/微代码比更多的取决于工作量。但通常Nehalem缓冲比Core 2要大。

   一个有意思的事情是Nehalem的LSD在概念上非常类似于跟踪Cache(trace cache)。跟踪Cache的目的是存储动态程序排序中的已经译码的微代码,来代替指令Cache中按照静态编译顺序排列存储的x86指令。因此将译码器和分支预测器从关键路径中去除,并允许多个基本块立刻被取出。P4的跟踪cache的问题是它太脆弱,当它没有命中的时候,就需要一条条指令重新译码。一般指令Cache的命中率可以达到90%以上,而跟踪cache的命中率比这个标准低很多,很少超过80%,通常低到50~60%。换句话说,40~50%的时间P4就像一个单发射的微处理器,而无法充分利用它的执行单元。LSD缓冲器几乎和跟踪cache是同一个目的,但当它无法工作(比如循环太大)的时候却不会带来像P4的跟踪cache那样的巨大痛苦。

   在LSD缓冲之后,译码中最后的一步是专用堆栈引擎,它去除了所有堆栈修改的微代码。堆栈修改的微代码都被一个专有的加法器执行并写到一个在前端中的推测增量寄存器中。之后,偶尔会和一个包含堆栈的非推测值的重命名结构寄存器同步。堆栈操作的微代码被清除后,剩下的微代码向下进入到乱序引擎中去重命名、发射、分派和执行。

七、乱序引擎和执行单元

   Nehalem乱序引擎被显著的扩大,除了性能的原因,更主要的是为了适应SMT。这大概是乱序引擎自设计以来最大的一次结构改变,因为SMT需要资源共享。

图3 乱序引擎和执行单元比较

   正如Core 2中那样,寄存器别名表(register alias table,RAT)指定每一个结构寄存器或者进入重排序缓冲(Re-Order Buffer,ROB),或者进入撤销寄存器文件(Retirement Register File,RRF),并保持大部分最近的推测状态(但撤销寄存器保持最近的非推测状态和已提交状态)。寄存器别名表每周期能够重命名4个微代码。在ROB中为每个微代码提供一个目标寄存器。重命名后的指令读他们的源操作并发射到统一的保留站(Reservation Station,RS),这个统一的保留站被所有的指令类型使用。

   在Nehalem中,ROB从96扩大到128项,而RS从32扩大到36项。ROB和RS在两个线程中共享,但用不同的规则。ROB是在两个线程之间静态地分配,这允许每个线程推测到指令流中相同远的地方。相反,RS是竞争共享,它是根据线程需要来分配,因为通常很多情况下线程会在等待一个存储器操作数的时候停顿,这将会使用相对较少的RS项,这时对这个线程较好的办法是放弃一些RS项给另一个更活跃的线程。那些在RS中操作数都准备好了的指令将被发送到执行单元。除了使用率提高外,Nehalem的执行单元与Core 2的执行单元相比,没做太大变化,也没受SMT的影响。

八、“豪华”的Cache结构

   Nehalem几乎在每个方面都得到了增强,尤其是存储子系统做了很大的变动,因为他关系到整个系统的结构。几乎存储系统的每个部分都细化、改进或改动了来支持更大的并行性,如图4所示。

图4 存储子系统比较

    改变从读取缓冲从32项增加到现在的48项,存缓冲从Core 2的20项扩大到32项开始,因为Nehalem将正在处理的读取和存储的数量增加了50%,原因是他们必须被两个线程共享,他们采用静态分配,这大概是因为关键路径的限制。

   读取与存缓冲之后,存储操作继续操作cache层,这个cache层也来了一个自顶向下的全部重新设计。和P4一样,cache和TLB都是根据已观测的行为在线程间动态共享。Nehalem的L1数据cache与上一代保持一样的大小和相联性,但是延迟从3个时钟增加到4个时钟以适应时钟约束。正如以前提及的,每个核能够支持更多的命中失败(上升到16)来利用额外的存储带宽。

   Nehalem中余下的cache层的设计和Core 2中的不一样。Core 2的最后一级cache是L2,它被两个核共享来降低一致性冲突和权重。L2 cache有6MB,24路相联,读取很慢,使用14-15个时钟的延迟。Nehalem的cache层次结构扩展到3层,前两层相对较小,且为一个核专有,L3cache很大并且是所有核共享。

   在Nehalem中,每个核都有专门的统一的256KB 8路相联的L2 cache,提供极快的数据和指令存取。读取所用的延迟没有公开,但英特尔的体系结构设计者Ronak Singhal声称延迟不会超过12个时钟。L2 cache相对L1 数据cache既不是包含的也不是互斥的。就像Core 2中那样,Nehalem能在两个核的专有cache之间传送数据,尽管不是全速传送。

   Nehalem是第一个封装一个大的共享L3 cache的主流英特尔处理器,2003年以来,许多像安腾和很多至强MP的英特尔的服务器设计需要L3 cache。AMD和英特尔的主流处理器都从来没有用过L3 cache的设计,直到去年(2007年)出现单片四核设计的Barcelona处理器。

   Nehalem的8MB16路相联L3 cache包含下层的L1、L2cache并由4个核共享。尽管英特尔没有讨论任何硬件设计,还是表露出L3 cache使用与核不同的电源层,而且操作在不同的频率下。这从节省能源和可靠性上都是有意义的,因为大cache在低电压下更敏感软错误。Nehalem读取所用的延迟变化依赖相关频率、核的相位差、L3本身一级存取L3的仲裁延迟。最好的情况下,例如操作的相差与频率差是整数倍,Nehalem的L3读取所用延迟根据英特尔的结构会在30到40个时钟的范围内。包含式Cache的好处是它能处理几乎所有的一致性问题而不需打扰每个独立核的专用cache。如果一次对L3的缓存存取失败,那么数据就不会出现在核的L2和L1 cache中。另一方面,Nehalem的L3也扮演着类似cache命中监听过滤器的角色。L3的每个Cache行包含4个“core valid”位,指明哪个核上的专有cache有该行上的数据的拷贝。当一个“core valid”位为0,那么那个核就不可能有那个cache行的拷贝;而如果“core valid”位为1,则有可能(但不保证)那个被考察的核有这一行数据的一个似有的备份。因为Nehalem使用MESIF cache一致协议,如果两个核有有效位,则cache行将保证是干净的(没有修改)。这两个技术的组合让L3 Cache能够尽可能的让每个核避免繁多的一致性冲突,释放更多的有效带宽给cache中的实际数据。

   实际上,包含式cache不是解决问题的唯一的方法,并且他们也有开销。一个非包含式cache能够通过简单地复制所有专有cache的标识到最后一级cache的标志文件,并在每次存取的时候同时检查最后一级标志与专用cache标志的方法达到同样的好处。包含式cache被设计用来强迫复制数据,这隐含着不同级cache的大小之间的某种关系。对于Nehalem,每个核包含64KB的L1数据cache。256KB的L2 cache。这意味着Nehalem的8MBL3 cache中的1~1.25MB被填上的数据也在其他cache中。Nehalem L3 cache的容量几乎是4个L2 cache容量的8倍,而Barcelona的L3 Cache和所有的L2 cache一样大。

   Nehalem的cache层次结构还增加了对非对齐操作的支持,使其更加灵活。英特尔以前的芯片对于16字节的SSE读取与存储总是用两种指令,一种保证数据对齐cache行的边界,而另一种是无需对齐的。后者由于吞吐量低,执行起来慢(即使数据实际上是对齐的),因此常常被编译器设法避免掉。Nehalem改变了这一状况,它使对齐操作和非对齐操作具有相同的延迟和吞吐量,同时也改进了非对齐操作对非对齐数据的存取性能。得到的结果是非对齐SSE读取或者存储总是具有和对齐存储器操作一样的延迟,因此就没有特别的理由一定要用对齐SSE存储器操作。

九、TLB、页表和同步

   和新的cache层次结构一起提出的还有Nehalem对TLB(Translation Lookaside Buffer,快表)结构的一些重要改动,TLB用来缓存虚拟地址到物理地址映射关系。Core 2的TLB安排的很有趣。L1 DTLB(英特尔有时候称它为Micro-TLB)做的非常小,而且只用来读取,它有16项4KB的页和16项更大的页(2MB或4MB)而且每个都是4路相联的。L2 DTLB比较大,而且服务于所有的存储器操作(L1 DTLB读取的失败和所有的存储操作)。它提供256项4KB页面和32项更大的页面(2M/4M),同样采用4路相联。由于Nehalem的cache层次结构包含更多的数据,因此也就需要加大TLB。

   Nehalem用一个真正的两级TLB层次结构代替了Core 2的预存在TLB,它能够动态地在SMT技术下的活跃线程之间分配。Nehalem的第一级DTLB为所有的存储操作服务,并包含64项4KB也和32项较大的2M/4M页,保持4路相联。Nehalem也设计了新的指令与数据统一的第二级TLB,它只包含512项小页,依然4路相联。

   在Nehalem与Core 2的TLB之间最重要的不同是他们覆盖cache的程度不同。在Core 2中,有6MB的cache并且TLB通过使用小页表(大多数应用不需要大页表)能够转换2176KB的存数空间,这样就有效地覆盖了1/3到一半的L2 cache(依赖与我们是否考虑Merom或Penryn)。相反,每个Nehalem核都有576项小页,而全片共有2304项。这么多的TLB项可以转换9216KB的内存,这样,只用小页就足够包含整个8MB的L3 cache,而且还有富余。

   Nehalem的TLB项通过引入“虚拟处理器ID”或称VPID技术,而做了巧妙的修改。每个TLB项将存储器中的一页从虚拟空间到物理空间的转换进行缓存。这种转换是特别针对给定的进程和虚拟机。当处理器在虚拟的客户端和主机之间进行切换的时候,英特尔的老CPU会刷新TLB来确保进程只操作允许他们操作的存储空间。VPID跟踪TLB中一个给定的转换相关联的VM,以便当VM退出和重进入的时候,TLB不需要因为安全问题而被刷新。取而代之的是如果进程试图操作一个没有关联的转换,它将会被简单地判为没有命中TLB,这比制造一个操作页表无效的非法操作要好。VPID通过降低VM变迁的开销,来增加虚拟化的性能。英特尔估计,Nehalem中VM来回变迁的延迟将是Merom(例如65nm Core 2)的40%,比45nm Penryn低1/3。

   另一个在Nehalem中虚拟化的调整是扩展的页表,它实际上消除了很多VM变迁(这比VPID只降低延迟要好)。常规的页表映射客户虚拟地址到客户的物理地址,然而,在虚拟化系统中,还有一种从客户物理地址到主机物理地址的转换。扩展的页表管理那些从客户物理地址到主机物理地址的映射,Nehalem将简单地通过扩展的页表消去很多不必要的VM退出,而早期的英特尔设计以及AMD Barcelona之前的设计都需要管理程序来处理页面失效。

   Nehalem也降低了诸如LOCK,XCHG和CMPXCHG这样的同步原语的延迟,这个对于多线程程序是很必要的。英特尔声称LOCK和CMPXCHG指令(将使得流水线串行化)的延迟是P4的20%(这绝对是恐怖的),大约是Core 2的60%。延迟下降了,但行为还是保持和过去的一样。Lock指令是不可流水化的,尽管新的操作能够在LOCK指令前执行。


   
CopyRight © 2003