你的位置:pcMing工作室 >> 资讯 >> 专业术语 >> 详细内容 在线投稿

Nehalem百科

排行榜 收藏 打印 发给朋友 举报 来源: 百度百科   发布者:未知
热度2275票  浏览239次 【共0条评论】【我要评论 时间:2010年6月14日 22:45

D gDw*d4TM`^0

G8vD"Jw*kJ6b~0  四、前端部分:(指令拾取和解码) pcMing工作室a6?pTt1J

pcMing工作室1FjQ6J:g

  1、指令拾取(包括分支预测)

#o-O5OZ%X0
pcMing工作室&t/I0h2pD8k2OPfd`&q

  在Nehalem的指令拾取单元(instruction fetch unit)中包含有相关指令指针(relative instruction point,RIP),每个线程状态(thread context)各有一个。在指令拾取单元中还包含有分支预测器,用来预测下一条将被拾取的指令的RIP。对于分支预测器的很多细节,INTEL并没有公布,但它们是适合于工作在SMT模式的。并且Nehalem也将继续使用上一代的那些特殊的分支预测器,比如循环检测器(loop detector),间接预测器(indirect predictor)等。 pcMing工作室#B5_%d!Wmf

pcMing工作室%op!q$AM.b

  当分支预测器选定一条分支时,分支目标缓冲(branch target buffer,BTB)就负责预测目标地址。Nehalem使用了2级BTB结构。作为参考,K10使用了一个有2K 项(entry)的BTB用于直接分支,和一个有512项的间接分支目标阵列(indirect branch target array)。Nehalem的两级BTB设计,非常适用于有大量指令代码的任务,例如数据库、ERP和其它的商业应用,通过提高分支预测准确度而提升性能和能效。INTEL没有发布详细的内部结构。下面作出一些有依据的猜测。

&BYg ]Y tn&n-h:iT${0

a N)}+} c&[0  有两种可能。一是两个BTB使用同样的预测算法,而一个存取更小一点的历史文件,包含最近时间内所使用的分支RIP和目标RIP。在这种情况下,它们的关系就象L1缓存和L2缓存一样(因为分支目标也具有相当好的地址相关性)。举个例子,比如L1 BTB有256-512项,而更大的L2 BTB则有2K-8K项。如果分支RIP在L1 BTB中没有找到,然后就到L2 BTB中去找,以作出目标预测。

e.h ]wYRm0

(T]*@Jz5k|0  另一种可能(RWT认为这种可能性比较小)则是两级BTB使用不同的预测算法和不同的历史文件。比如L1 BTB使用简单而快速的算法和相对较小的历史文件,而L2 BTB则使用更慢但更准确的算法,而且被配置成是具有优先权的预测器。如果L2 BTB不同意L1 BTB的预测,则它可以撤消(override)L1 BTB的预测,去除掉流水线中错误拾取的指令,而从新预测的RIP处重新拾取指令。这种结构可能性不大,因为它的能效比较低下。对于这种预测器架构,通常的情况是L1和L2 BTB都独立的得出正确的分支目标——这就意味着在大多数的时间里,L2 BTB都是在浪费能源。而L1 BTB错误,L2 BTB是正确的情况,只占非常小的比例。 pcMing工作室Q VGHv$X

WP f qnY n_(e%s0  不过在更早一点的ANANDTECH的文章中有提到认为是第二种方式:通常会遇到这样的情况,L1 BTB作出预测是基于分支的类型,但实际上它并没有历史数据,这样准确度就很低。而L2 BTB有更多的历史数据,就可以提高准确度,而且L2 BTB可以在执行过程中就纠正(L1 BTB所给出的)错误预测,而避免性能损失(这就正是override的情况)。 pcMing工作室jB9jq$@9B XP

pcMing工作室/hlM#EFj&\

  现在不清楚哪一种观点更正确一些。 pcMing工作室 I*uS2tC6F*u$l

pcMing工作室%J6lTfF-ad]

  Nehalem另一个提升分支目标预测的机制是对返回堆栈缓冲(return stack buffer,RSB)进行了重命名。当发生程序调用时,RSB就记录下地址,这样当结束调用返回时,就从该地址继续执行下去。但是当有很多程序递归调用时,RSB将会溢出,并且如果分支预测错误,那么也将会产生错误的返回地址。Nehalem通过重命名RSB,就避免了溢出。并且错误的分支预测也不会毁坏RSB,只要调用与返回地址是正确配对的,那么就可以从Nehalem的RSB中得到正确的数据。对于每一个线程都有一个专用的RSB,避免任何交叉弄脏数据。

F9kA Y b0
pcMing工作室pM,Q4dP7otD

  拾取单元取得了每一个线程预测的下一个地址(通常情况下也就是正确的下一个地址),就到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的指令队列则只是作为指令被解码前的缓冲,因为它的循环缓存在流水线级数中,被放到了解码阶段的后面。

J1jfJb;n#a*GK0

&f8ru2r,e.Kt-d0  2、解码

b1n!g0O1wx5]LF0

&v C3h6V!t0  当X86指令进入指令队列后,它们就等着被解码成微操作指令(uop),这是一种类似于RISC的指令。Core 2和Nehalem都有4个解码器,一个复杂解码器和3个简单解码器。简单解码器能够处理可以解码成一个uop的X86指令,现在绝大多数SSE指令都是这种。复杂解码器能够处理解码成1-4个uop的X86指令,而比这还要复杂的指令,则由微代码序列器(microcode sequencer)来处理。

S?6U8bv U6o0

d$z:m!eo5w De0  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操作系统了。 pcMing工作室K$th?B4U

pcMing工作室 f_+R(o5P%Q Zj

  一旦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缓冲。

F,H3D%{%bFN0
pcMing工作室obFu+Z sQu4{6e

  比较有趣的是,Nehalem的LSD缓冲看起来更象是指令追踪缓存(trace cache)。指令追踪缓存的目标是以动态程序的顺序来存储微操作,而不是象指令缓存里那样以静态编译顺序存储X86指令,因此可以从关键路径(critical path,指需要时间最长的路径)中去掉解码器和分支预测器,而使得被堵塞的地方可以立刻取得指令。P4的指令追踪缓存的问题在于它太脆弱了,当其命中失败时,就必须一个接一个地(重新)解码指令。通常指令缓存的命中率是在90%以上,而指令追踪缓存却远低于这个标准,很少时候超过80%,大多数时候是在50-60%。也就是说,在40-50%的时间里,P4都表现得象是一个单发射微处理器,而不能够完全利用上它的执行资源。而Nehalem的LSD缓冲取得了和指令追踪缓存几乎同样的目标,而且当它无法工作的时候(即当循环太大时),也没有什么要命的性能损失。

#H`WaH0

3o)a8{/NDak0  在LSD缓冲之后,解码步骤的最后一步是专用堆栈引擎(dedicated stack engine),除去所有被堆栈更改过的微操作。堆栈更改过的微操作都是被一个专用加法器给执行过了的,并写到前端的一个推测寄存器(speculative delta register)。推测寄存器偶尔会和重命名结构的寄存器(renamed architectural register)同步,而重命名结构寄存器中则保存有堆栈中的非推测值(non-speculative value)。当堆栈处理过的微操作都被清除之后,剩下的微操作就进入乱序执行引擎去被重命名、发送、分配和执行。 pcMing工作室Zz8WG#^ k_\

pcMing工作室~^Lz B

  五、乱序引擎和执行部分:(Out-of-Order Engine and Execution Units)

}6w#u"Qbi0

!I.Q'B)|5l%^0  Nehalem的乱序引擎显著的扩大了,除了性能原因,还有就是为了提供SMT,因为SMT需要资源共享。 pcMing工作室d3R0pcQ| ^ H/b

pcMing工作室3|G"YB/[&i4X i

  和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,可以被各种指令类型使用)。 pcMing工作室U7phL#g1Rjq?:~

+g2~3D5l-G%lcy6K^0  Nehalem的ROB(重排序缓冲)从96项增加到128项,RS(保留站)从32项增加到36项,它们都由两个线程所共享,但是使用不同的策略。ROB是静态分配给2个线程,使得2个线程在指令流里都可以预测得一样远。而RS则是竞争共享,基于各线程的需求。这是因为许多时候一个线程可能会中止,从内存等待操作数,而使用到很少的RS项。这样就不如让另一个更活跃的线程尽可能多地使用RS项。在RS中的指令当其所有操作数都准备好时,就被分配到执行单元去。 pcMing工作室f"w` |WpN)X

pcMing工作室 h3^? Q heRA!q

  Nehalem的执行单元与Core 2相比,基本没有大的改变,而且并不受SMT的影响,除了使用率更高之外。 pcMing工作室^6h2qv0M%Rv/jKT

pcMing工作室9V3t iW&c(J

  六、缓存结构

+L'Bk}%zcu5]0
pcMing工作室tk"E2Neub`r(Z

  几乎Nehalem的所有方面都是略为改进并增强,但存储子系统(memory subsystem,或翻译为内存子系统)却是非常激烈的大修理。 pcMing工作室^_vx G

1u9p^.|o%H*H*o0  Nehalem可以同时运行的读取和存储量增加了50%,读取缓冲由32项增加到了48项,而存储缓冲由20项增加到了32项(增量还略多于50%)。增加的原因自然是为了让两个线程共享,这里采用的是静态分配,可能是由于关键路径的限制。 pcMing工作室 E4_5v3]8n

k!N o?L&n2a@nv0  从读取缓冲和存储缓冲,存储操作就继续访问到缓存架构。Nehalem的缓存架构是完全革新了的。象P4一样,所有的缓存和数据TLB(Translation Lookaside Buffer,旁路转换缓冲,或叫页表缓冲)都是由2个线程动态共享(根据已经观察到的行为)。Nehalem的L1 D(一级数据缓存)保留了和Core 2一样的大小和联合度(associativity),但是延迟却从3个周期增加到了4个周期,以适应时间限制(timing constraint)。另外前面已经说到,每一个核心可以支持更多的未解决的命中失败(outstanding miss),最多到16个,可以利用更多的存储带宽。 pcMing工作室3\;M)m5@d;|#]

pcMing工作室}8xR4P-p*f:N

  而Nehalem剩下的缓存结构则和Core 2截然不同。Core 2的最后一级缓存是L2,由2个核心共享,这样可以减少一致性错误(coherency traffic),数量达到了24路联合的6MB(Penryn),延迟是14-15个周期(Conroe是14,Penryn是15)。而Nehalem有3级缓存,前两级相对较小,是每个核心私有的,而L3则非常大,由所有核心共享。

B _ O(] D0iy jk;T0

/~]U U$d7Wo9a[(I0  Nehalem的每个核心有一个私有的通用型L2,是8路联合的256KB,访问速度相当快。其使用延迟时间还没有完全披露,不过INTEL的工程师表明是小于12个周期的。Nehalem的L2相对于其L1D来说,既不是包含式(inclusive)也不是独占式(exclusive),就象Core 2一样,Nehalem可以在两个核心的私有缓存(L1D和L2)之间传递数据,尽管不能够达到全速。

3z+OS(x+?y0

&E(`]+tZ3u:W F0  Nehalem的16路联合、8MB的L3对于前两级来说,是完全包含式的,并且由4个核心共享。尽管INTEL并没有完全说明Nehalem的物理设计,但似乎L3缓存是单独使用电力,并运行在单独的频率上。这是从节省电力和可靠性这两个方面推断出来的,因为大的缓存更容易在低电压下产生软错误(soft error)。这样,L3使用延迟就取决于相对频率、核心的相差(phase alignment)、L3自身,还有访问L3的仲裁器的延迟。在最好的情况下,即操作相差和频率差距是整数倍的情况下,Nehalem的L3使用延迟是在30-40周期(根据INTEL工程师的说法)。 pcMing工作室%F!hf*bKwT3k#[

s?$A2vB+L%U.A0  使用包含式缓存的好处是可以处理几乎所有的一致性流量问题(coherency traffic),而不需要打搅到每个独立核心的私有缓存。如果在L3中发生命中失败(cache miss),那么要访问的数据就肯定也不在任何一个L2和L1中,不需要侦听其它内核(而独占式缓存,则还要回头去检查其它内核)。

@;qB&b }^-K} @:Db8[0
pcMing工作室Z$@1f\.b b$HR

  另一方面,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可以尽可能的让每个核心避免数据一致性错误,这样就给出更多的实际带宽。 pcMing工作室`/y@"]0UT+Uq-u

pcMing工作室 N2q F^a7@O3n%k

  事实上,并非只有包含式缓存这一种解决之道。对于非包含式缓存来说,通过和最后一级缓存一起复制所有私有缓存的标志文件(tag file),并同时检查所有的最后一级缓存的访问标志和私有缓存的访问标志,也可以达到同样的性能好处,并避免数据一致性错误。而包含式缓存则是设计得必须复制数据,这就能够表明各级别之间大小的一定关系。Nehalem的每个核心有64KB L1D和256KB L2(有可能L1D的数据包含在L2中,也可能L1D的数据并没有包含在L2中。因为L2并非包含式),这就意味着在8MB的L3中,有1-1.25MB的数据是前两级缓存中也有的数据。这就是包含式缓存额外的开销。

v ^/S2DXEB0
pcMing工作室0b2Hb`5AG0q@wX

  Nehalem的缓存架构设计得也更容易支持非对齐(unaligned)的访问,有更快的非对齐缓存存取。INTEL前几代芯片一直是用两种类型指令来做16Byte(128bit)的SSE读取和存储,一种是其数据必须正好和缓存行(16B)对齐,比如MOVAPS/D、MOVDQA指令——(数据)必须刚好是16Byte,和缓存行对齐。另一种则可以是未对齐的,比如MOVUPS/D、MOVDQU指令,数据对齐与否是没有要求的。

sMtMsel&v4oLI0
pcMing工作室%YR X Q)R*b

  在Nehalem之前,处理对齐的指令更有优势,而处理非对齐的指令则更慢、具有更低的数据吞吐量(即使其数据是在对齐的情况下),需要多个微操作。编译器也总是避免后一种指令,尽量避免非对齐的读取,象MOVSD+MOVHPD这样的2条连续指令就会更快一些。

e2nX"Wc4I2N%jG0
pcMing工作室!K%l)rl*U|S

  而Nehalem则对非对齐指令进行了优化:在存取对齐数据的时候,非对齐指令和对齐指令具有一样的延迟和吞吐量。同时也提高了非对齐指令对于非对齐数据的访问速度。这样,不管是什么类型的SSE操作,都具有相同的延迟。另外Nehalem对在存取数据时跨越了64-Byte缓存行边界的情况也进行了优化,比起Core 2具有更低的延迟和更高的吞吐量。这样,编译器就不会再惧怕使用非对齐的指令了。 pcMing工作室f mxl(r*v`*t

pcMing工作室KbVt;g

  七、TLB,虚拟化性能

.R%rl6J&gAF6t K,S0

)Z|7l0oo&a0  除了改变缓存架构,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路联合。

2E7T.l7cB(?0
pcMing工作室g9b;w3B(G4Jwx

  Nehalem则建立起了真正意义上的两级TLB体系,可以动态分配给SMT的活跃线程状态(thread context)。Nehalem的L1 DTLB可以做所有的存储访问(可以读取和存储),它有64项小页表和32项大页表,也都是4路联合。而新的L2 TLB是通用型的(可以用于指令和数据),它只有512项小页表,也是4路联合。

@IoUBT|/?/z0

/s:|:n|!Pz0  Nehalem和Core 2的TLB的一个明显的差异是它们覆盖缓存的深度不同。Core 2(Penryn)有6MB L2,通过使用小页表(绝大多数的应用都不使用大页表),TLB可以转换2176KB的内存(地址),这样就覆盖了1/3的L2。而Nehalem的一个核心有576项小页表,整个CPU总共则是2304项,这样TLB就可以转换9216KB的内存,这已经超过8MB L3的容量了。 pcMing工作室 Vtmy@2vS(b9M`&n

pcMing工作室!{ z fPO"KPb

  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%)。 pcMing工作室tU7v"T7A]d#AN

9tH+s(KV0  Nehalem另一个虚拟化方面的改变是扩展页表(Extended Page Tables,EPT),用来消除许多VM地址转换,即减少转换次数(而VPID的作用是降低VM地址转换的延迟)。通常的页表是用来匹配客户机的虚拟地址和客户机的物理地址,然而在一个虚拟化系统中,也有从客户机的物理地址到主机的物理地址的转换。INTEL早期的CPU(和AMD在Barcelona之前的CPU)将需要系统管理程序(hypervisor)来处理页面错误,而Nehalem则通过EPT,来消除了许多不必要的虚拟机退出。 pcMing工作室$rR5F?*g2Dvn*m

:e}a5e1\)t.G0

顶:137 踩:123
对本文中的事件或人物打分:
当前平均分:-0.43 (708次打分)
对本篇资讯内容的质量打分:
当前平均分:-0.21 (654次打分)
【已经有653人表态】
111票
感动
90票
路过
75票
高兴
65票
难过
86票
搞笑
63票
愤怒
84票
无聊
79票
同情
上一篇 下一篇
发表评论
换一张

网友评论仅供网友表达个人看法,并不表明本网同意其观点或证实其描述。

查看全部回复【已有0位网友发表了看法】

网络资源