Conroe优势分析 Core vs K8架构解析
宽动态执行(Wide Dynamic Execution),高级数字多媒体增强技术(Advanced Digital Media Boost),智能内存访问技术(Smart Memory Access),高级智能缓存技术(Advanced Smart Cache)――这些都是 Intel 的市场部人员重点宣传的技术,所有的这些技术造就了 Intel 新推出的高性能、低功耗的 Core 微架构。不过,我们不会只关心市场宣传人员给他们的产品贴上的漂亮的标签。如果只看标签的话――“结合良好的性能与合理的功耗,扩展数字生活的方式”,你会发现这与 VIA 对他们的 C7 处理器的宣传很相似。然而,你认为宣传口号背后的 Intel Core 微架构会与 VIA C7 处理器相同吗?
下面,就让我们来仔细了解一下隐藏在市场宣传人员的口号背后的 Core 微架构的秘密,并且与 AMD 的 K8 微架构、Intel 之前的 NetBurst 微架构以及 Pentium M 处理器进行对比。撰写这篇文章之前,我们与 Intel 以色列研发中心(Israel Development Center,简称IDC)的架构设计师之一――Jack Doweck 进行了交流。Jack Doweck 设计了全新的内存乱序缓冲区(Memory Reorder Buffer)和内存相关性预测系统(Memory disambiguation system)。
Intel 的市场宣传人员声称 Core 微架构是 Pentium M 处理器和 NetBurst 微架构的融合。然而目前比较普遍的看法是,Core 微架构是 Pentium Pro 架构,或者说是 P6 微架构的延续。在 Core 微架构中,你很难找到任何与Pentium 4,或者说是 NetBurst 微架构有关的东西。在我们与 Jack Doweck 的交谈之后,这个事实更加清晰――Core 微架构中只有预取机制是从 NetBurst 微架构获得的灵感,所有其它的设计都是从 Yonah 微架构(Core Duo 处理器)演变而来,而 Yonah 微架构显然是从 Banias 处理器和 Dothan 处理器演变而来的。所有 Banias、Dothan、Yonah和采用 Core 微架构的处理器都继承了 NetBurst 处理器的前端总线设计,但除此之外,它们毫无疑问都是曾经获得巨大成功的 P6 微架构的后代。在某种意义上,你可以把 Core 微架构叫做“P8 微架构”,因为 Banias 和 Dothan 处理器曾经被称作“P7 微架构”。(不过,需要注意的是,Intel 从未给出过 Banias 和 Dothan 处理器所采用的微架构的正式名称,我们一般用 Pentium M处理器代表它们,或者简称为 PM 处理器。)
不过这并不意味着 Intel 的工程师只是把 Yonah 处理器的一些功能单元和解码器重新包装一下然后换了个名字就推出来。Jack 告诉我们,Woodcrest、Conroe 和 Merom 处理器都是基于 Yonah 处理器的,但是几乎80%的架构和电路设计需要重新进行。
为使那些不熟悉处理器设计的读者也能理解文章后面的内容,我们首先从一个处理器微架构的速成教程开始。为了理解处理器设计的目标和优劣,你首先需要了解处理器执行的指令,所以我们从处理器运行的软件开始。
典型的 X86 程序的代码中大约有50%的指令是存储器访问指令,其中存储器读指令大约是存储器写指令的2倍。然后,大约15%到20%的指令是分支指令(if, then, else等)。剩余指令中,大部分是诸如“ADD”、“MUL”这样的较简单的计算指令。像“DIV”、“SQRT”这些较复杂的计算指令在所有指令中只占很少的一部分。所有这些指令都按照典型的流水线步骤执行:取指,解码,取操作数,执行,退出。
首先,处理器会根据指令指针寄存器(instruction pointer register)指示的地址取回指令。这时,对处理器来说,指令仅仅是一些没有意义的0、1字符串。只有在被解码之后,指令对处理器来说才开始有意义。指令被解码后可以得到操作数地址和操作码,而操作数地址可以在下一步发挥作用:取操作数。你不会希望处理器对操作数的地址进行计算,而是对那些地址里面存放的内容进行计算――与 C 语言里面的指针的概念很相似。当操作数被取出来以后,ALU根据操作码的指示,就可以对操作数进行正确的计算了。计算结果一般将被写回处理器内部的寄存器堆中。有时候,计算结果也需要写回到缓存和内存中。这就是最后的步骤――退出。到此为止,你应该略微了解一条指令的整个执行过程了。
今天,对处理器设计者来说,主要的挑战是处理器的存储器访问平均延迟。在一个由 Pentium 4 3.6GHz 和 DDR400 内存构成的系统中,处理器的速度是内存的速度(200MHz)的18倍。也就是说,访问内存的每一个周期,处理器会经过18个周期。而且,发送一个内存访问请求需要多个内存周期,回应一个内存访问也需要多个周期。因此,对于 Pentium 4 来说,花费200到300个处理器周期来等待内存访问的完成并不罕见。设计处理器缓存的目标就是避免内存访问的发生。但即使处理器缓存的缺失率仅为4%,也就是说,在处理器访问存储器的所有情况中只有4%的比例需要访问内存,这4%也将显著降低处理器的执行效率。
在处理器频率已经达到3GHz甚至更高的时代,保证即将用到的指令和数据已经在缓存中准备好是处理器设计者最重要的工作之一。因为只有这样,才能保证随着处理器频率的提高性能也随之提高;否则的话,更高的处理器频率只会使处理器花费更多的时钟周期来等待数据。这种把数据提前装入缓存的技术被称为“数据预取技术”(Prefeching)。但是,之前的处理器采用的数据预取技术并不能保证每次都成功,总会有一些失败的情况。这会导致处理器性能降低,特别是在运行对带宽敏感的应用程序的时候。
Core 微架构所采用的数据预取技术毫无疑问是目前为止最先进的,要优于 Pentium 4 和 Athlon 64 所采用的技术。Core 微架构中的每个核心至少有3组预取单元,包括2组数据预取单元和1组指令预取单元。除此之外,共享式二级缓存还拥有2组预取单元。这样,在一个双核心的采用 Core 微架构的处理器中,共有8组预取单元。有一个问题是,多达8组的预取单元在进行预取工作时,很容易会妨碍到正在运行的程序的正常的 load 操作。为了避免这种情况的发生,Core 微架构采取了预取监测器的机制,该监测器总会给予正在运行的程序更高的优先级。这样,预取单元就决不会从正在运行的程序那里“偷”走很多带宽了。
Core 微架构的预取机制还有更多新特性。数据预取单元经常需要在缓存中进行标签查找。为了避免引起正在运行的程序进行的标签查找的更高的延迟,数据预取单元使用标签查找的 store 端口。如果你还记得,load 操作的发生频率是 store 操作的2倍之多,那么就容易理解这样的选择了――store 端口的使用频率仅为 load 端口的一半。并且,store 操作在大多数情况下并不是影响系统性能的关键,因为在数据开始写入后,处理器可以马上开始进行下面的工作,而不必等待写入操作完成。缓存/内存子系统会负责数据的整个写入到缓存、复制到主内存的过程。
Core 微架构的缓存系统也令人印象深刻。二级缓存容量高达4MB,并且是由两个核心共享的,访问延迟仅12到14个时钟周期。每个核心还拥有32KB的一级指令缓存和一级数据缓存,访问延迟仅仅3个时钟周期。从 NetBurst 微架构开始引入的追踪式缓存(Trace Cache)在 Core 微架构中消失了。NetBurst 微架构中的追踪式缓存的作用与常见的指令缓存相类似,是用来存放解码前的指令的,对 NetBurst 微架构的长流水线结构非常有用。而 Core 微架构回归相对较短的流水线之后,追踪式缓存也随之消失,因为 Intel 认为,传统的一级指令缓存对短流水线的 Core 微架构更加有用。
下面的表格不仅包括了 Core 微架构和 K8 微架构的存储子系统的特性,还包括了之前的 K7 处理器、Pentium M 处理器及 Pentium 4 处理器等的存储子系统的特性。
[img]http://article.pchome.net/00/12/15/61/clip_image001.jpg[/img]
缓存结构比较
通过浏览该表格,很快就可以发现,Core 微架构的存储子系统给人留下非常深刻的印象。它不仅拥有最大容量的二级缓存,而且还拥有较低的缓存访问延迟。共享式二级缓存的设计还可以使单个核心享用完全的4MB缓存。一级缓存和二级缓存的总线位宽都是256-bit,从而可以给核心提供最大的存储带宽。
Core 微架构面对的最重要的竞争对手是 AMD 的 K8 处理器。从表格中也可以看出,K8 处理器在存储子系统上也并非全面处于下风,而是拥有两个值得注意的优势。
首先是较大的一级缓存:64KB的一级指令缓存和64KB的一级数据缓存。不过 K8 处理器的一级缓存采用2路组相连结构。相比之下,Core 微架构采用的8路组相连结构的32KB的一级缓存并不会差多少。
第二个优势是更加重要的一个:K8 处理器拥有集成在处理器内部的内存控制器。这样的做法大大降低了内存访问延迟。不过,采用 Core 微架构的处理器的更快的前端总线也有效降低了内存访问延迟。就我们目前所知道的,K8 处理器在内存访问延迟上的优势会缩水到仅仅15%~20%,而不是与Pentium 4相比较时的几乎加倍的速度(45~50纳秒对比80~90纳秒)。
即便如此,K8 处理器的这两项小小的优势也有可能被与 Core 微架构存储子系统其他方面的比较抵消掉。Core 微架构的处理器比竞争对手 K8 处理器拥有更大的二级缓存和更加智能化的预取机制。Core 微架构的处理器的一级缓存拥有大约2倍于 K8 处理器的带宽(ScienceMark 软件测试的结果),而其二级缓存的速度更是2.5倍于 K8 处理器的二级缓存。
与 K8 处理器类似,Core 微架构会对取出的指令进行预解码。预解码信息包括指令长度和解码边界。
Core 微架构装备了4组解码单元,这是X86处理器世界的第一次。这4组解码单元包括3组简单解码单元和1组复杂解码单元。实际上,这种把简单指令与复杂指令分而治之的做法,并非是 P6 微架构的专利。从全世界第一个流水线化的X86处理器――80486开始,为了加速简单指令的执行,这原则就已经开始主导所有高速X86处理器的微架构。就算是号称提供三组“完整解码单元”的 AMD K7、K8 处理器,实际上也有类似的限制。
在介绍下面的内容之前,首先让我们解释一下什么是微指令(Micro-Op)。由于X86指令集的指令长度、格式与定址模式都相当复杂,为了简化数据通路(Data Path)的设计,从很久以前开始,X86处理器就采用了将X86指令解码成1个或多个长度相同、格式固定、类似RISC指令形式的微指令的设计方法,尤其是涉及存储器访问的 load 及 store 指令。所以,现在的X86处理器的执行单元真正执行的指令是解码后的微指令,而不是X86指令。
所以,对X86处理器来说,解码单元的任务不仅仅是解码出操作码和操作数的地址,还要把长度从1字节到15字节不等的X86指令转化成容易调度和执行的固定长度的类似RISC指令的微指令(Micro-Op)。
常见的普通X86指令可以由3组简单解码单元中的任何一组翻译成1条微指令。另外1组复杂解码单元负责解码一些复杂的、需要翻译成4条微指令的X86指令。还有一些更长、更复杂的X86指令,需要微码序列器配合复杂解码单元来翻译成微指令。这种简单解码单元与复杂解码单元相配合的解码方式被现代的X86处理器所普遍采用,包括 P6 微架构、K7 处理器、K8处理器和 Pentium 4 处理器。
Core 微架构中的解码单元还拥有更多新特性。首先是宏指令融合技术(Macro-Op Fusion)。该技术可以把2条相关的X86指令融合为1条微指令。例如,X86比较指令cmp可以与跳转指令jne融合。这类情况一般发生在程序中的if-then-else分支语句中。
[img]http://article.pchome.net/00/12/15/61/clip_image002_0000.jpg[/img]
宏指令融合技术
宏指令融合技术带来的效果是非常明显的。在一个传统的X86程序中,每10条指令就有2条指令可以被融合。也就是说,宏指令融合技术的引入可以减少10%的指令数量。而当2条X86指令被融合的时候,4组解码单元在单周期内一共可以解码5条X86指令。被融合的指令在后面的操作中完全是一个整体,这带来几个优势:更大的解码带宽,更少的空间占用,和更低的调度负载。如果 Intel 宣称的“每10条指令可以融合1次”的说法属实,那么宏指令融合技术本身就将带来巨大的性能提升。
另外一项技术即微指令融合技术,是从之前的 Pentium M 处理器继承而来的。介绍这项技术之前,我们先来了解一下相关的问题和早期的解决办法。有一小部分X86指令处理起来非常困难,但是同时又是十分典型和常见的X86指令。一般来说,存储器寻址的算术操作就属于这一类指令,例如,ADD [mem], EAX。这表示把寄存器EAX的内容与地址为mem的内存单元的内容相加,并把计算结果写回该内存单元。
在早期的处理器设计中,包括采用 P6 微架构的Pentium Pro、Pentium II 和 Pentium III 处理器,如果遇到这种类型的指令,那么解码单元将把它解码成2条甚至3条微指令。记住,从 P6 微架构之后的现代X86处理器的设计思想是把X86指令解码成类似RISC指令的微指令,然后再把这些微指令送往越来越RISC化的后端,而后端以类似RISC处理器的处理方式进行调度、发射、执行和退出。
对于类似ADD [mem], EAX这样的指令,你没有办法送往RISC化的执行单元,因为它违反了 RISC 架构的根本规则――RISC 架构的处理器会把所有的数据 load 到寄存器,然后针对寄存器进行操作、计算等。
因此,ADD [mem], EAX这条指令会被解码成多条微指令,简单示意如下:
MOV EBX, [mem]:读取[mem]的内容到寄存器
ADD EBX, EAX:对2个寄存器作ALU操作
MOV [mem], EBX:保存计算结果到[mem]
自从 Banias 处理器之后,上面的load操作和ALU操作就可以用一条微指令来完成了。Intel 把该技术称为微指令融合技术(Micro-Op Fusion)。这项技术不是一件容易的事情:在旧的设计中,把load操作与ALU操作一起进行会导致对应的那一级流水线延迟加大,从而降低处理器所能达到的最高频率。(在处理器设计中,可能达到的最高频率取决于最慢的那一级流水线的延迟时间,即所谓的木桶效应。)只有可以并行执行、设计优秀的电路才使得在引入微指令融合技术的同时不显著降低处理器的频率。
在预解码的阶段,处理器会识别可以应用微指令融合技术的指令。在解码阶段,类似 ADD [mem], EAX 的复杂指令就可以生成比旧架构数量更少的微指令。与宏指令融合技术带来的效果类似,这可以带来更大的解码带宽,更少的空间占用,更低的调度负载和更高的效率。
微指令融合技术的目的就在于减少微指令的数目。处理器内部执行单元的资源有限,如果可以减少微指令的数目,就代表实际执行的X86指令增加了,可以显著提升执行效能。而且,微指令的数目减少还有助于降低处理器功耗,可谓有益无害。
微指令融合技术所支持的范围,包括了整数运算、浮点运算和SSE2指令集等各种扩展指令集。根据 Intel 的官方说法,通过微指令融合技术,整数运算大约可以提升5%的性能,浮点运算大约可以提升9%的性能。
Core 微架构前端的改进还包括分支预测单元。分支预测行为发生在取指单元部分。首先,它使用了很多人们已经熟知的预测单元,包括传统的 NetBurst 微架构上的分支目标缓冲区(Branch Target Buffer,简称BTB)、分支地址计算器(Branch Address Calculator,简称BAC)和返回地址栈(Return Address Stack,RAS)。然后,它还引入了2个新的预测单元――循环回路探测器(Loop Detector,简称LD)和间接分支预测器(Indirect Branch Predictor,简称IBP),其中循环回路探测器可以正确预测循环的结束,而间接分支预测器可以基于全局的历史信息做出预测。Core 微架构在分支预测方面不仅可以利用所有这些预测单元,还增加了新的特性:在之前的设计中,分支转移总是会浪费流水线的一个周期;Core 微架构在分支目标预测器和取指单元之间增加了一个队列,在大部分的情况下可以避免这一个周期的浪费。
接下来让我们来看一下这有趣的对比:Core 微架构的3组简单解码单元与1组复杂解码单元 vs. K8 处理器的3组复杂解码单元。
K7 处理器有2种解码方法,向量路径(Vector Path)和直接路径(Direct Path)。向量路径解码会生成多于2条的类似RISC的指令(AMD称为Macro-Op,即宏指令)。直接路径解码会生成1条或者2条宏指令。K7 处理器的每组解码单元都可以进行向量路径解码和直接路径解码,但是从性能的角度讲,直接路径解码无疑是更好的选择,因为它会生成数量较少的宏指令。怎么,你觉得突然谈论 K7 处理器有点奇怪?不,因为就像 Core 微架构是基于 P6 微架构一样,K8 处理器很大程度上也是基于 K7 处理器的。
K7 处理器的3组复杂解码单元是强大的,可以解码绝大多数X86指令,只有很少一部分指令需要使用向量路径解码。它们仅有的缺点是一些浮点指令和SSE指令需要使用向量路径解码。而 K8 处理器拥有更强大的复杂解码单元――几乎所有的浮点指令和SSE指令都可以使用直接路径解码了。这是因为K8 处理器的取指与解码单元的流水线比 K7 处理器的更长。当涉及到SIMD指令时,K8 处理器尤其强于 K7 处理器。
显然,Intel 的宏指令融合技术在AMD 的 K8 处理器上并不存在。但是,AMD拥有与微指令融合技术类似的技术。首先需要注意的是,Intel 与 AMD 使用的名词“宏指令”与“微指令”具有不同的含义,很容易使人混淆。这里我们给出下面的表格,对它们进行分辨。
[img]http://article.pchome.net/00/12/15/61/clip_image002.jpg[/img]
名词辨析
在 Athlon 处理器中,也存在有微指令融合技术。例如,一条 ADD [mem], EAX 指令在真正执行前中始终保持为一条指令。因此,它在缓冲区中也只会占据1个单元的空间。不过,在 Core 微架构中 load 操作和 SSE 操作等也可以被融合,而 K8 处理器则不行,它会把SSE操作解码成2条宏指令。
那么,在解码单元方面,Intel 的 Core 微架构与 AMD 的 K8 处理器比较的结果是什么呢?就目前的资料来看,还很难确切的说到底哪个更加有实力。不过,我们有一个初步的看法:Core 微架构要更具有优势。因为在一般情况下,它每个时钟周期可以解码4条X86指令,加上宏指令融合技术的话则最多可以解码5条X86指令。而 AMD 的 K8 处理器每个时钟周期只能解码3条。
总而言之,AMD 的3组复杂解码单元胜过 Core 微架构的3组简单解码单元加上1组复杂解码单元的情况不大可能发生。仅当多条复杂指令同时需要复杂解码单元进行解码的时候,K8 处理器的解码单元会胜过 Core 微架构的解码单元。但是考虑到实际程序中的绝大多数X86指令对应简单解码单元的事实,这种情况不大可能发生。
为了使读者更加清晰的了解AMD K8 处理器与 Intel Core 微架构的区别,我们使用相同的风格制作了下面的图表。
[img]http://article.pchome.net/00/12/15/61/clip_image004.jpg[/img]
Core 微架构
[img]http://article.pchome.net/00/12/15/61/clip_image005.jpg[/img]
K8 处理器
从图上可以看到Core 微架构与K8 处理器的明显区别。Core 微架构拥有更大的乱序缓冲区――96 entry,再考虑到它的宏指令融合技术,其实际容量比 K8 处理器的72 entry要大的多。而最初的 P6 微架构只有40 entry,在Banias、Dothan 及 Yonah 处理器中增加到了80 entry,而现在的 Core 微架构进一步增加到了96 entry。为了看起来清晰、直观,我们制作了下面的表格来比较这几代处理器的重要特性。
[img]http://article.pchome.net/00/12/15/61/clip_image006.jpg[/img]
几代处理器特性比较
Core 微架构采用集中式保留站(central reservation station),而 K8 处理器采用分布式调度器(distributed scheduler)。集中式保留站的优势是拥有更高的利用率,而分布式调度器能容纳更多的表项。NetBurst 微架构也采用分布式调度器。
使用集中式保留站也是把 Core 微架构称作“P8 微架构”的理由之一,这是相对古老的 P6 微架构的第二项巨大的提升。它利用保留站并调度与分配执行单元来执行微指令。执行结束后,执行结果被存储到乱序缓冲区内。这样的设计方式无疑是继承自Yonah、Dothan 甚至 P6 微架构。
最大的区别并不能立即从图表上看出来。Intel 先前的处理器需要2个时钟周期才能完成一次分支预测操作,而 Core 微架构只需要1个时钟周期。而 AMD 的 K8 处理器也只需要1个时钟周期就可以完成一次分支预测操作。
另外一处令人惊讶的地方是 Core 微架构的 SSE 多媒体指令执行性能。Core 微架构拥有3组非常强大的128-bit的 SSE 执行单元,其中2组是对称的。拥有如此强大的SSE执行资源,Core 微架构在执行128-bit SSE2/SSE3指令时将远远超过 K8 处理器。
在 K8 处理器上,1条128-bit的 SSE 指令会被解码成2条64-bit的指令,因为 K8 处理器的 SSE 执行单元只能执行64-bit的指令。所以说,从这个角度看,Core 微架构的SSE处理能力至少是 K8 处理器的2倍。如果是对64-bit的浮点进行操作,Core 微架构每个时钟周期可以处理4个双精度浮点数的计算,而 K8 处理器可以处理3个。
就整数执行单元来说,Core 微架构比 Pentium 4 处理器和 Dothan 处理器也有很大的提高,而与 K8 处理器处于同样的水准――如果只考虑执行单元的数量的话,Core 微架构与 K8 处理器都拥有3组ALU。如果也考虑 AGU 的话,K8 处理器拥有3组,甚至比 Core 微架构的2组要更有优势。这可能会使 K8 处理器在一些不太常见的整数计算中有优势,比如解密运算。不过,Core 微架构拥有的更深、更灵活的乱序缓冲区和更大、更快速的二级缓存可以在绝大多数整数运算中消除 K8 处理器这个小小的优势。
自从采用 P6 微架构的 Pentium Pro 处理器之后,X86 处理器开始拥有乱序发射和执行指令的能力。不过,乱序缓冲区内平均大约三分之一的指令很难重排序――就是那些 load 操作。把 load 操作提前执行可以极大的提高性能。与需要数据的时候才进行 load 操作相比,尽可能早的开始 load 操作十分有用,因为这可以更有效的把一级缓存及二级缓存的延迟隐藏掉。
这很容易理解。假设现在有一个 ALU 操作需要某数据,可是该数据不在一级缓存中。如果 load 该数据的操作在该 ALU 操作之前就已经执行完毕,那么访问二级缓存的延迟就不会对性能产生影响。不过,需要注意的是,如果 load 操作针对的数据在程序中还有 store 操作要对其进行写入,那么就不能把 load 操作提前到该 store 操作之前执行。因为这样的情况下,如果提前执行 load 操作的话,意味着你得到的会是错误的数据,而不是最新的。
[img]http://article.pchome.net/00/12/15/61/clip_image007.jpg[/img]
Intel 内存相关性预测技术
上图中的 Load 2 操作不能提前执行,因为它操作的数据与 Store 1 操作的数据相同,需要等待 Store 1 操作先完成。只有 Store 1 执行完毕,数据Y才拥有正确的值。不过 Load 4 操作没有理由不能提前进行,它不需要等待 Store 1 或者 Store 3 操作完成。这样,通过把 Load 4 操作提前,load 单元有更多的时间去获得正确的操作数。
不过,之前的处理器在这种情况下――有 store 操作存在――都不会把 load 操作提前。因为处理器不知道 store 操作针对的数据单元与 load 操作是否相同。如果想要搞清楚是否相同的话,需要计算存储器地址。这十分困难,因为在指令乱序和调度的时候,存储器地址还是未知的。
这时需要注意一个事实:load 操作读取到一个错误数据的概率相当小,只有1%到2%。所以,Intel 的 Core 微架构设计师 Jack Doweck 决定,允许所有的 load 操作提前执行,假设所有的 load 操作读取到的数据都是正确的。而为了应对错误的发生,Intel 加入了一个预测器。
根据 Jack Doweck 的描述,以及我们对以前的 P6 微架构和 Pentium M 处理器的了解,我们制作了下面的图表。注意这并非 Intel 官方的图表。
[img]http://article.pchome.net/00/12/15/61/clip_image009.jpg[/img]
Core 微架构乱序执行引擎
预测器做出预测,并指示乱序缓冲区是否可以把某 load 操作提前执行。在 load 操作提前执行之后,冲突监测单元会扫描MOB(Memory Reorder Buffer),查看是否有 store 操作与 load 操作冲突。如果有冲突发生的话,load 操作必须重新执行,这时大约会损失20个时钟周期。不过与之前的处理方式相比,Core 微架构采用的这种处理方式总体上肯定可以提高处理器的效率。
检测某 load 操作和某 store 操作是否是针对同一内存地址的行为称作内存相关性预测(memory disambiguation)。Core 微架构允许 load 操作提前到 store 操作之前执行的处理方式可以带来性能上的巨大提升。在某些测试代码中,这个提升甚至达到了40%。虽然我们在实际的应用程序中不会看到如此大的提升,但是无疑这项技术会带来令人印象深刻的提升――我们可以期待10%到20%的性能提升。
不要忘记,load 操作可能是所有操作中最重要的操作。不仅仅因为 load 指令占了X86处理器内所有微指令的三分之一强,还因为当 load 操作发生时可能导致的巨大延迟会引起处理器的等待。那么,这项极其灵活的 load 操作乱序执行技术与其它架构的处理器相比是什么情况呢?
[img]http://article.pchome.net/00/12/15/61/clip_image010.jpg[/img]
Load 操作处理方式比较
旧的 P6 微架构和 Penium M 处理器也已经可以较好的处理 load 操作,可以把某 load 操作提前到另外的 load 操作之前进行,也可以提前到已知不会发生冲突的 store 操作之前进行。P6 微架构的内存乱序缓冲区(Memory Reorder Buffer,简称MOB)采用如下的规则:如果在乱序执行窗口中存在与某load操作内存地址相同的store操作,则该load操作不能提前执行;如果在乱序执行窗口中存在内存地址未知的store操作,则任何load操作不能提前执行;某store操作不能提前到另外一个store操作之前执行。
相比之下,K8 处理器要逊色的多,它只能把 load 操作移动到不相关的 ALU 操作之前进行,而不能移动到其它 load 操作之前,当一个 load 操作等待某 store 操作执行的时候,处理器会浪费大量的时钟周期。这意味着 K8 处理器在指令乱序这方面受到极大的限制。
这也许是 K8 处理器在游戏和整数计算等方面输给 Core 微架构的最重要的原因之一,尽管它拥有延迟更低的内存子系统和更多的整数执行资源。整数运算进行的存储器操作经常有许多未知的地址需要计算,而浮点运算则不是这样,它对存储器的访问是更加规范的。这也是 K8 处理器在浮点运算方面不输给 Dothan 处理器的原因之一。
当 load 操作和 store 操作都已经进入 Load/Store 单元的队列中的时候,K8 处理器允许 load 操作在不冲突的 store 操作之前执行。不幸的是,这时把 load 操作提前执行已经不能隐藏缓存缺失所带来的延迟。你可以认为这是 K8 处理器拥有的 Load/Store 乱序机制,但是它在流水线中的位置太靠后,比起 P6 微架构、Pentium M 处理器和 Core 微架构所采用的技术相差甚远。
Core 微架构拥有庞大的执行资源和巨大的共享式二级缓存,看起来是非常适合应用 SMT(Simultaneous Multi Threading)技术的处理器设计。但是,Intel 并没有在 Core 微架构中应用 SMT 技术。其原因并不是 SMT 技术不能带来好的结果。Intel 的工程师接受的任务是研发拥有极佳性能的、可以适应服务器和桌面系统和移动系统等多种平台的处理器。而SMT技术只有在服务器平台上才能带来最大的性能提升――最高可以达到40%。因此以色列团队的工程师们决定放弃SMT技术。另外,SMT技术还会使处理器中发热最大的部分更热,所以说,SMT 并不适合 Core 微架构的“单个微架构统一所有平台”及“功耗最优化平台”的设计思想。
至于引入集成式内存控制器(Integrated Memory Controller,简称IMC),Intel 的工程师表示花费在内存控制器上的晶体管不如放到二级缓存上。这个观点当然会引起极大的争议。不过有一点是可以肯定的:二级缓存的功耗会比内存控制器更小。Intel 的这个选择也许是因为把内存控制器放到芯片组上使得他们可以在不改变处理器设计的情况下支持新类型的内存。考虑到 Intel 的桌面平台和移动平台使用 DDR2 内存模组,而服务器平台将使用 FB-DIMM 内存模组,这样做的灵活性就很明显了。改进的内存相关性预测技术及预取单元等可以弥补不集成内存控制器带来的损失。那么,集成内存控制器会提高 Intel 处理器的性能吗?几乎是肯定的,但是 Intel 目前还在考虑其它的选择。
Intel Core 微架构很明显是曾经取得过巨大成功的 P6 微架构的继承者。不过,它加入了很多新的特性和设计,比如微指令融合技术、宏指令融合技术、内存相关性预测和庞大的 SIMD 及浮点执行资源。
与优秀的 AMD K8 处理器的设计相比,采用 Core 微架构的处理器是更宽、更有效率、更加乱序化的处理器设计。当我们对 Jack Doweck 提出“Core 微架构中庞大的执行资源需要 SMT 技术才能完全利用”的观点的时候,Jack Doweck 表示不同意。全新的内存相关性预测技术从指令级并行的层次上把 load 操作的并行性提高了一大块,而 Core 微架构强大的一级缓存与二级缓存带来的高带宽可以帮助处理器把执行单元的利用率保持在与 Pentium M 处理器相近的水平上。这样,与时钟频率相同的 Pentium M 处理器相比,Core 微架构多出的三分之一的执行资源可以获得接近三分之一的性能提升。
那么,对 AMD 来说,是否意味着“Game Over”?首先,我们几乎可以肯定,在 AMD 下一代的处理器上肯定会有一些明显的变化。然后,现在还不能说 K8 处理器的生命周期已经结束了。AMD 可以做的一种明显的升级措施是增强其处理器的 SSE 执行性能,可以通过增加执行单元的位宽,或者增加浮点流水线中的执行单元的数量。
为了保证浮点单元的实力得到充分的发挥,AMD 应该提高处理器缓存的带宽。旧的 K7 处理器的二级缓存相当慢,而 K8 处理器已经可以把二级缓存能够提供的带宽加倍。我们可以期待 AMD 在未来的处理器的二级缓存上使用256-bit的总线位宽。
最后,AMD K8 处理器的整数性能也还有很大的提升空间。K8 处理器对 load 操作的乱序执行并不优秀,这是从 K7 处理器开始就存在的弱点。实际上,我们知道 AMD 的设计师对此非常清楚,但是在 K8 处理器上没有做出改进非常令人惊讶。如果能够更加有效的对 load 操作进行乱序执行,即使不能达到 Core 微架构所采用的内存相关性预测技术的效果,也可以期待5%的性能提升。这也是 Pentium M 处理器能够在某些类型的应用程序中击败 K8 处理器的重要原因之一。
这些只是一些我们熟悉的方面。除此之外,可能还会有更多的措施可以使 K8 处理器延续的更久。
再来看一下采用 Core 微架构的服务器产品Woodcrest,考虑到服务器应用程序中能够发挥指令级并行能力的地方并不多,Core 微架构没有应用超线程技术应该是它仅有的缺点。这个小缺点是 Core 微架构的设计思想导致的,因为 Core 微架构需要顾及服务器平台、桌面平台和移动平台。这也许会使 Sun 公司和 IBM 公司在某些需要进行多线程应用的服务器平台上得到机会。不过,采用 Core 微架构的4核产品 Tigerton 很快就要到来,也许可以弥补这个劣势。那么,现在我们的读者应该清楚了:你很难从 Core 微架构中找出明显的缺陷。
不过,具有讽刺意义的是,就在一年前,Intel 还并不重视提升IPC(Instructions Per Clock)和ILP(指令级并行能力)。多核被认为是未来的发展趋势,而单核的性能似乎无关紧要。因此在 Dobbs 博士的文章中曾经提到“The free lunch is over”(免费的午餐结束了),他认为以后只有增大缓存才能带来IPC的微弱提升,开发者把注意力集中在处理器的IPC效率上的日子已经一去不复返了。一些研究者甚至认为,具有简单的、顺序执行的架构的处理器才是未来的方向。
我们却非常怀疑“Threading is our only savior”(多线程是唯一的救世主)。Unreal 3 游戏引擎的开发者 Tim Sweeney 曾经指出,在下一代游戏引擎中开发多线程的代码是非常大的挑战。宽流水线、高频率的处理器被否定得有一些过快。NetBurst 微架构的设计使用了 LVS 电路设计的策略来实现极高的频率,而 Core 微架构并没有采用这种策略。但是,它仍然是一个采取极宽流水线的、采取乱序执行策略的处理器,这是那些不想花费太大力气在编写多线程应用程序上的程序员的免费的午餐。从这个角度来说,对双核处理器发展的需求可能不会那么太迫切。让用户得到更高的性能是软件开发者和处理器设计者共同的责任。是的,双核是好东西,但是单核的性能仍然重要。
[color=gray][ 本帖最后由 一水 于 2006-7-21 22:08 编辑 ][/color]
页:
[1]