Intel, AMD及VIA CPU的微架构(39,完)

21. 微架构的比较

已经调查的最先进微架构代表了不同的微架构核心:AMD,Pentium 4(NetBurst),Pentium M与Intel Core 2核心。现在我将讨论这些微架构的优缺点。我不讨论内存带宽的差别,因为这部分依赖于内部硬件及缓存大小。这4个微架构类型都有不同缓存大小的不同版本。因此,微架构的比较主要与CPU密集应用相关,与内存密集应用不那么相关。

21.1. AMD K8与K10核心

这个AMD微架构比Intel处理器的微架构要简单一些。这有一定的好处,因为处理器在复杂逻辑上消耗的资源更少。它也有次优乱序调度方面的缺点。通过一个全程3路的流水线,仅仅得到每时钟周期3个宏操作的吞吐率。从一个流水线移动宏操作到另一个流水线的能力有限。

执行单元不如Intel处理器那么特化。所有3个整数执行单元都可以处理几乎所有整数操作,甚至包括最晦涩、少用的指令。只有整数乘法单元太昂贵,不能做到3个单元里。这个通用性使得路径简单,代价是更大的执行单元。

3个浮点执行单元特化程度高些。仅最简单的浮点被多个单元支持。宏操作在3个浮点单元间的分派远不算最优。这里有一定的改进空间。

混用不同时延宏操作,浮点执行单元还有问题。这个问题以一个相当复杂且低效的方式处理,通过阻塞一个短时延宏操作的分派,如果能预测它将与之前一个更长时延宏操作同时需要结果总线。一个更简单、更有效的解决方案应该是将一个短时延宏操作的结果保存在流水线,直到结果总线可用。这可以解决,如果流水线被长时延宏操作统治,短时延宏操作将被长时间拖延的问题,而且它可以消除预测结果总线何时空闲的复杂逻辑。

所有执行单元有相当短的时延且完全流水线化,因此可以每时钟周期接受一个新的宏操作。

据说在同一时钟周期里9个执行单元(3个整数ALU,3个地址生成单元,3个浮点单元)可以执行9个宏操作。但是,几乎不可能通过实验验证这个声明,因为回收阶段被限制为每时钟周期3个宏操作。换而言之,AMD有大量的、永远不会用完的执行资源。如果在回收阶段的瓶颈被拓宽,那么将有可能每时钟周期执行更多的宏操作。

AMD每条指令产生相当少的宏操作。即使读-修改与读-修改-写指令也仅产生一个仅在流水线的执行阶段分解为微操作的宏操作。这类似于PM与Core2设计里的融合微操作。AMD K8设计没有大于64比特(原文为byte)的执行单元,因此在AMD K8中,128位XMM指令产生两个宏操作。后续的AMD K10在浮点流水线中有128位单元,在一个宏操作中处理向量指令。

AMD设计对一个宏操作上的输入依赖没有严格限制。因此,像ADC EAX, EBX,CMOVBE EAX, EBX与MOV [EAX+EBX], ECX的指令都有一个宏操作实现。在可比较的Intel处理器上,相同的指令必须分解为至少2个微操作,其中一个微操作不能有超过2个输入依赖,包括条件标记。

在K10上指令获取的吞吐率已经从每时钟周期16字节增加到32字节。在被采用跳转后,仍然有一个较低的吞吐率。2级缓存的指令获取特别慢。

指令解码看起来相当高效。每时钟周期可以解码至少3条指令。

对总是去往相同方向的分支,分支预测良好,因为分支预测信息同时保存在1级缓存与2级缓存中。但预测规则分支模式的机制有比Intel处理器低的预测正确率。

缓存系统每时钟周期可以进行两次内存读,而Sandy Bridge之前的Intel处理器每时钟周期仅能进行一次读。

21.2. AMD Bulldozer,Piledriver与Steamroller内核

Bulldozer微架构是之前模型的一个重大的改进。

Bulldozer有2到8个计算单元,每个有两个CPU核。代码缓存,指令获取器,分支预测,及浮点单元都在每个计算单元的两个核间共享。在计算单元中仅使用一个核时,该设计允许每时钟周期最多4条指令的吞吐率,在两个核都使用时,每时钟周期2条指令。

大多数执行单元是加倍的,使大多数指令可以每时钟周期两条的吞吐率执行。

浮点指令与整数向量指令的时延通常比Intel Sandy Bridge要长些。

对浮点操作的单线程吞吐率是每时钟周期2个128位操作,这可以是加法、乘法或融合乘加。

AMD设计对一个μop上的输入依赖数没有严格限制。因此,像ADC EAX, EBX,CMOVBE EAX, EBX及MOV [EAX+EBX], ECX指令都以一个μop实现、在Intel处理器上,相同的指令必须分解为至少两个μop,其中一个μop可以有不超过2个输入依赖,包括条件标记,除了融合乘加指令。

指令解码器每时钟周期可以处理4条指令。Bulldozer与Piledriver每单元有一个解码器,由两个线程共享,而Steamroller每线程有一个解码器。每时钟周期4条指令的最大吞吐率最好通过混用整数指令与向量指令来获得。

在Bulldozer中缓存系统很差,Piledriver好些,Steamroller还要好些。

21.3. ​​​​​​​AMD Zen核心

在落后Intel几年后,Ryzen处理器让AMD重回竞技场。Zen核心有每时钟周期5条指令的吞吐率,是目前为止的记录,128位向量代码的吞吐率特别高。Ryzen每时钟周期可以计算4个128位浮点向量,或两个256位向量。

在单线程应用中要充分利用提升的指令级并行,高吞吐率加重了程序员与编译器的负担。核吞吐率是如此高,每核运行两个线程是合理的,不像其他某些核吞吐率较低的处理器,因为两个线程竞争有限资源,可能会看到严重的性能下降。

新的μop缓存是一个重要改进,它消除了在大多数关键循环里指令获取与解码的瓶颈。

在所有层级大缓存是一个特别重要的改进。但缓存带宽限制在每时钟32字节,比最好的Intel处理器要小。

21.4. ​​​​​​​Pentium 4核心

Intel Pentium 4(NetBurst)核心的设计片面强调时钟频率。导致就市场与声誉而言,这个时钟频率确实有优势,但就使高时钟频率可行的设计考虑而言,它有相当高的代价。需要长流水线,因为每流水线阶段,电路做更少的工作。在P4微架构中,某些流水线步骤只是用来从芯片的一部分移动数据到另一部分。在高频率下,物理距离变得重要。长流水线意味着高的误预测惩罚。

每个执行单元保持尽可能小。不仅因为物理距离重要,而且因为散热也是一个限制因素。越小的单元越特化,可以处理更少不同操作。这意味着除了最简单的指令,其他指令都要求多个μop,某些指令还要求许多μop。

1级数据缓存也相当小(8或16kb),但2级缓存的访问是快速的。

P4没有像其他处理器那样有代码缓存,但有一个追踪缓存。追踪缓存以一半时钟频率运行,可能因为其大小。追踪缓存不保存原始代码,而是已解码μop。这些μop非常类似于RISC指令,因此核心可以使用RISC技术。在解码是瓶颈时,在缓存前将指令解码为类似RISC的μop是合乎逻辑的。在某些其他处理器上解码或预解码是瓶颈的情形中,P4确实性能更好。

但追踪缓存没有看起来那么先进。例如,一条PUSH或POP指令在代码缓存中仅需要1个字节,但在P4E追踪缓存中需要16字节。这意味着在相同面积的芯片上,能缓存的代码更少。另外,在追踪缓存中,相同的代码可能出现在多个追踪里。在缓存大小是受限物理因素时,导致缓存里代码更少。32位P4在追踪缓存中有一些数据压缩,但这与使解码简单、高效背道而驰。在跳转到代码其他部分时,把代码安排到追踪缓存消除了获取时延,但在跳转到另一个追踪时,仍然有时延,而且因为追踪缓存以一半时钟频率运行,这个时延更高。是否将相同的代码保存到多个追踪是在消除跳转与将更多代码放入追踪缓存之间权衡。

不管怎么说,我严重怀疑追踪缓存使得设计更简单。我不知道如何记录追踪、将物理地址映射到多个追踪缓存地址、确定是否跳转到另一个追踪或扩展一条分支指令上现有的追踪,以及确定何时重排追踪。对我而言,这像一个逻辑的噩梦。

指令解码器每时钟周期仅可以处理1条指令,而其他设计每时钟周期可以解码3条或更多的指令。显然,解码器有低优先级,因为仅在从2级缓存构建新追踪时使用它。

P4有两个执行端口用于ALU与其他计算(端口0与1),两个额外端口用于内存操作与地址计算(端口2与3)。每个执行端口有1或多个执行单元。同时向两个不同的执行单元分派两个μop是不可能的,如果它们使用相同的执行端口。因此,这些端口是瓶颈。在端口0与1之间,执行单元没有最优地分布。所有浮点与SIMD(向量)操作,除了简单的移动,去往端口1。这使得在浮点与SIMD代码中,端口1是一个严重的瓶颈。

两个小整数ALU以2倍时钟频率运行。32位P4可以仅半个时钟周期的虚拟时延进行错开的加法。对条件标记的时延更长。64位P4E仍然使用双倍速ALU,但时延是一个时钟周期。对可由这两个ALU处理的指令,吞吐率是每时钟4个μop。双倍速ALU特化来仅处理最常用的操作,比如在通用寄存器上的移动与加法。

其他执行单元有更长的时延,有时长得多。最讽刺的例子是在P4E上浮点寄存器到寄存器移动的7时钟周期时延。在来自一个执行单元的结果作为另一个执行单元的输入时,还有一个额外时钟周期的时延。

一条128位XMM指令由一个μop处理,都能执行单元一次仅可以处理64个比特,因此吞吐率仅是每时钟周期64比特。只有内存读才有每时钟周期128位的吞吐率。这使得对会使用128位操作的内存密集应用,P4/P4E是一个高效的微架构。

分支预测算法尚可,但出于两个原因,误预测惩罚不同寻常地高。第一个原因显然是长的流水线(20或更多步骤)。第二个原因是在误预测分支里的伪μop,在回收前没有被丢弃。一个误预测通常涉及45个μop、如果这些μop是除法或其他耗时的操作,那么误预测会代价极高。其他微架构一旦检测到误预测,可以尽快丢弃μop,使它们不再徒劳地使用执行资源。

相同的问题适用于未就绪写转发的内存操作数的假读。P4将持续重演这个读,连同依赖它的后续μop,直到内存操作数就绪。在一个写后读的内存依赖里,这会浪费许多执行资源。这通常出现在参数在栈上传送到一个例程时。在缓存不命中与其他事件后,还存在μop的一个过量重演。在执行伪μop上浪费的资源数是如此高,它是一个严重的性能问题。

回收限制在每时钟周期略少于3个μop。

21.5. ​​​​​​​Pentium M核心

PM是旧的Pentium Pro核心的一个改进,关注点是降低功耗。大量工作放在在执行单元与总线不使用时,关闭它们。更低的功耗有有利的一面。低功耗意味着可以增加时钟频率,而不会使芯片过热。

指令解码受4-1-1规则限制(第79页)。为了优化指令解码,必须特别地按4-1-1规则调整软件。不过,4-1-1模式被指令获取边界打破,对程序员或编译器作者,这很难预测。这个问题将指令获取速率降低到每时钟周期小于16字节,解码速率降低到每时钟周期少于3条指令(第79页)。在PM设计中,指令获取与解码绝对是弱的一环。

执行单元围绕5个执行端口集中,以一个非常类似于P4的设计。端口0与1用于ALU与其他计算。执行单元在端口0与1间的分布更加均匀,许多μop可以去往任一个端口。这使得保持两个端口忙碌,比P4设计要容易。

使用2个执行端口都有的ALU,SIMD整数指令相当高效,时延仅1时钟周期。浮点时延也相当低。

PM每指令产生的μop要少于P4。而这两个设计都有每时钟3个μop的吞吐率,PM每时钟周期执行的指令更多,因为较低的μop数。低的μop数部分由于μop融合(第80页),以及栈指针的一个专用加法器(第82页)。不过,μop融合机制不能作用于XMM寄存器。这使得PM对MMX寄存器及浮点寄存器比XMM寄存器更有效率。

PM有每时钟周期从永久寄存器文件3个寄存器读的限制。这很可能是一个瓶颈。

PM有一个先进的预测机制。循环计数器是我们已经期盼多年的东西。但这不足以补偿非常小的、可能只有128项的分支目标缓冲。改进的预测间接跳转的能力可能是减小BTB大小的必要条件。

PM不支持64位指令集。

回收阶段的吞吐率与P4完全相同。虽然这两个设计都限制在每时钟周期3个μop,PM有更少的每指令μop,以及在执行单元更短的时延。这使得PM如此高效,可能比P4更快地运行CPU密集代码,虽然后者的时钟频率高50%。

21.6. ​​​​​​​Intel Core 2与Nehalem微架构

这个设计吸取了PM成功的哲学,更进一步地关注低功耗。低功耗使增加时钟频率成为可能。

扩展流水线与执行单元,以允许每时钟周期4个μop的吞吐率。通过每指令发布更少的μop,将数据总线与执行单元扩展到128位,这个吞吐率被进一步增加。缓存与内存带宽也被提升了。

Core2页Nehalem有如此多的执行单元与执行端口,因此执行阶段很少成为瓶颈。大多数执行单元与内部数据总线被扩展到128位,不像Intel与AMD之前的x86处理器,它们仅有64位执行单元。

不过,在设计中几个弱点仍然存在。我准备在这个设计中指出3个与流水线余下部分性能不匹配的部分,这些弱点很可能是瓶颈:

  1. 指令预解码。指令获取与预解码机制已经改进,但带宽仍然限制为每时钟周期16字节。在CPU密集代码里,这很可能成为瓶颈。
  2. 寄存器读端口。这个设计每时钟周期可从永久寄存器文件读不超过2或3个寄存器。在许多情形里,这可能是不够的。
  3. 分支历史模式表。分支历史模式表太小了,它可能连累原本相当先进的分支预测机制。
  4. 读端口。Core2每时钟周期可以读一个内存操作数,而AMD处理器可以读两个。读端口不总能匹配执行单元的高吞吐率。​​​​​​​

21.7. ​​​​​​​Intel Sandy Bridge及更新的微架构

这个新设计是一个重大改进。在Sandy Bridge里处理了之前设计的许多瓶颈。

在Intel设计中,多年来指令获取与预解码都是一个严重的瓶颈。在NetBurst微架构中,尝试通过缓存已解码μop来解决这个问题,不太成功。在Sandy Bridge设计中,在解码前后缓存指令。因此,μop缓存有限的大小不那么成问题,μop缓存看起来非常高效。

自旧的Pentium Pro起,有限的寄存器读端口就是一个严重且通常被忽视的瓶颈。在Sandy Bridge中这个瓶颈最终被消除。

之前的Intel处理器仅有一个内存读端口,而AMD处理器有两个。在许多数学应用中,这是一个瓶颈。Sandy Bridge有两个读端口,因而消除了这个瓶颈。

分支预测通过更大的缓冲与更短的误预测惩罚得到改进,但没有循环预测器,且误预测仍然相当常见。

AVX指令集是一个重要的改进。在使用新的256位YMM寄存器时,浮点加法与乘法的吞吐率加倍。对降低寄存器压力以及避免寄存器移动指令,新的非破坏性3操作数指令相当便利。不过,对混用有与没有VEX前缀的向量指令,有一个严重的性能惩罚。如果遵守编程指引,这个惩罚很容易避免,但不经意地混用VEX与非VEX指令是一个常见的编程错误,而且这样的错误很难检测。

一旦从一个系统消除最窄的瓶颈,第二窄的瓶颈将成为限制因素。在Sandy Bridge中要求关注的新瓶颈有以下这些:

  1. μop缓存。这个缓存理想地可以保存最多1536个μop。在大多数情形里,实际使用率远低于此。程序员应该注意确保最关键的内层循环能放入μop缓存。
  2. 指令获取与解码。自之前多个处理器以来,获取/解码速率都没改进,对不能放入μop缓存的代码,仍然是一个潜在的瓶颈。
  3. 数据缓存库冲突。增加的内存读带宽意味着缓存冲突的频率将增加。在最大限度使用内存端口的程序中,缓存库冲突几乎不可避免。在Haswell处理器中,这个问题已经被解决了。
  4. 分支预测。虽然分支历史缓冲与分支目标缓冲可能比之前的设计大,误预测仍然相当常见。
  5. 线程间的资源共享。在并发多线程(超线程)打开时,许多关键资源在一个核的两个线程间共享。在多个线程依赖相同的执行资源时,关闭并发多线程可能是明智的。

22. 低功耗微架构的比较

Intel Atom,VIA Nano,以及AMD Bobcat都是为低功耗设计的小处理器。这些处理器有比更高功耗处理器低的性能,但对普通的办公应用、嵌入式应用,甚至低流量服务器足够了。低价钱与低功耗使这些处理器,对要求不那么高的应用,是一个好的选择。

22.1. ​​​​​​​Intel Atom微架构

Intel Atom是比Core性能低的、小的低功耗处理器。它没有乱序执行能力,仅在某些相当严格的条件下,可以并发执行两条指令,就像15年前的第一代Pentium处理器。不过,内部设计与Pentium很不一样。

Atom设计的主要缺点是顺序执行与相对低的指令获取速率。

并发多线程支持用处有限,因为两个线程间共享的资源相当少,甚至对单线程使用也不足够。某些版本有每个能运行两个线程的两个核。

22.2. ​​​​​​​VIA Nano微架构

VIA Nano是一个面向与Intel Atom相同类型应用的低功耗小处理器。Nano有一个相当先进的乱序流水线与强大的执行单元。在某些方面,执行单元的性能类似于Intel与AMD大得多的桌面处理器。浮点性能特别好。

对内存访问与跳转,Nano的时延比桌面处理器长,但整数与浮点计算的时延非常低。对单线程应用,总体性能显著好于Atom。有两个或更多独立核的版本在多线程环境中提供了良好的性能。

22.3. ​​​​​​​AMD Bobcat微架构

AMD Bobcat有一个高性能且没有明显瓶颈的高效乱序流水线。执行单元仅是64位,对向量指令提供了较低的吞吐率。Bobcat有两个独立的核,在多线程环境中提供了良好的性能。

22.4. ​​​​​​​结论

AMD、P4与Intel Core设计都可以每时钟最多3个μop的最大吞吐率乱序执行指令。Core2,、Nehalem与Sandy Bridge每时钟可执行4个μop。在高度混用整数与向量指令时,AMD Bulldozer与更新的设计每时钟可以执行4个μop。

NetBurst(Pentium 4)设计有更高的时钟频率,意味着每时钟更多μop。但在NetBurst上,每条指令产生比其他处理器更多的μop,意味着每时钟更少的指令。高时钟频率的进一步劣势是长流水线,因而高的分支误预测惩罚。NetBurst微架构有如此多固有的性能问题,它没有继续下去。

PM、Core与AMD设计都使用较低时钟频率但每指令更少μop的相反策略。这个策略看起来对CPU密集应用提供了最好的性能。对许多指令,NetBurst有比其他处理器长的时延。这使得对有长依赖链的代码,它处于劣势。

所有这些设计都有一个类RISC的、工作在简单μop而不是复杂指令的执行核心。NetBurst与Sandy Bridge设计通过缓存μop而不是指令,将RISC哲学推得更远,NetBurst设计无法使人信服,因为它降低了每缓存面积的信息量,且追踪缓存的管理相比一个CISC解码器,没有节约时间。Sandy Bridge使用在解码前后缓存指令的折衷方案。结果看起来相当成功。

AMD使用在代码缓存中标记指令边界的不同策略,借以消除了指令长度解码的瓶颈。Intel在Pentium MMX中做了相同的事情,我不理解为什么他们遗漏了这个策略。在Intel处理器中,指令长度解码继续成为一个严重的瓶颈。这个问题通过缓存已解码指令得到缓解,但NetBurst追踪缓存的容量与Sandy Bridge的μop缓存仍然受限,因为μop比CISC指令更占缓存空间。

多年来,RISC哲学被视为通向高性能的最佳之路。Intel Core微架构以及AMD设计展示了偏离RISC、回归CISC原则的一个新趋势。P4的类RISC设计带有非常长的流水线与长的哲学时延,没有说服力,并且追踪缓存看起来效率低下。回归CISC设计的好处有3重:

  1. 紧凑的CISC代码更好地支持有限的代码缓存区域。
  2. 每指令更少的μop支持流水线更高的带宽。
  3. 每指令更少的μop支持更低的功耗。

CISC设计的主要缺点是,指令解码成为一个瓶颈。因为在代码缓存中保存指令边界的技术,AMD处理器有比Intel设计更高的解码带宽。Intel设计仍然被限制为每时钟周期16字节代码,在许多情形下这是不够的。

一开始的RISC哲学要求所有指令应该有相同的时延,以提供一个平滑的流水线。不过,这个原则很快被证明站不住脚,因为乘法、除法以及浮点加法比整数加法需要更多时间。在Intel微架构中,这个问题通过把不同时延的微操作发送到不同执行端口得到部分解决(参考第98页表8.1)。

在Intel Core及更新的设计中对节能特性的日益关注,使得使用一个相对高时钟频率成为可能,尽管是一个每流水线阶段要完成比NetBurst更多工作的设计。

AMD也使用一个每时钟周期几个μop的CISC设计。早期版本保持尽可能简单,以降低必要的逻辑开销。不过,这降低了乱序能力,以及执行单元的优化使用。

Intel Core与AMD K10处理器有完全128位的执行单元。更早的处理器在计算一个128结果时,使用一个64位单元两次。因此,在这些处理器中不可能完全利用128位XMM指令。Sandy Bridge有完整的256位执行单元,除了内存读与写操作。我们将很可能看到AMD的处理器或支持AVX的VIA使用128位单元两次来计算一个256位向量结果。在未来把向量大小扩展到512位或更大时,可能会发生相同的事情。

在AMD、P4与PM中每时钟周期3个μop的吞吐率,在Core2与更新的设计中,提升到4个μop,但我不预期这个数字在将来会提升得很多,因为更高吞吐率的优势没有被完全利用,除非代码内在有高度的并发性。

相反,潮流是多执行核。不过,在单用户系统中,我们需要多线程程序来充分利用多核。不能分解为多个线程的计算不能很好利用多核或多处理器。

许多微处理器有多个核。在NetBurst中引入了一个并发多线程技术(超线程)中间解决方案,并在Nehalem与Sandy Bridge中再次引入。微处理器有两个共享同一个执行核的逻辑线程。如果两个线程竞争相同的资源,这样的好处有限,但如果性能受限于别的其他,比如内存访问,并发多线程会有相当的优势。某些处理器在这两个线程间共享所有的资源,而其他处理器仅共享部分资源。这使得确定运行一个特定微处理器上的特定程序,并发多线程是否有好处,对程序员而言相当复杂。32位架构到64位的扩展已经是一个合乎逻辑且必要的事情。Intel走在AMD前面,带着先进的Itanium RISC架构,但它缺乏市场要求的前向兼容。AMD加倍了寄存器数的64位架构,仍然维持前向兼容,已经被证明是一个Intel不得不效仿的商业成功。今天,所有x86处理器都支持x64指令集。

下面的表22.1比较了这3个设计上各种操作的执行时延。一个比较缓存大小的表在手册4“指令表”里提供。

典型执行时延

AMD

P4E

Core2 45 nm

Sandy Bridge

整数加法

1

1

1

1

整数乘法

3

10

3

3

整数除法,32

40

79

23

28

封装整数移动

2

7

1

1

封装整数加法

2

2

1

1

封装整数乘法

3

8

3

3

浮点移动

2

7

1-3

1

浮点加法

4

6

3

3

浮点除法,双精度

20

45

21

22

浮点向量加法

4

5

3

3

浮点向量乘法

4

7

5

5

表22.1. 指令时延的比较

23. 未来的趋势

NetBurst设计中的高时钟频率被证明在功耗与芯片发热方面代价过高。这导致了注意力从吉赫兹竞赛转向。自此,对功效的关注持续增加,在未来这个因素不会减弱,因为小型的电池供电计算机变得非常流行。

执行单元的速度与计算能力比内存访问速度增加得更快。因此,可以预期在未来,在提升缓存与内存带宽上有强烈的关注。3级缓存与更宽的数据通路将普及。

在现今微处理器上,因为长的流水线,分支误预测代价很高。我们将很可能看到更先进的多级分支预测算法,更大的分支目标缓冲与历史表,多个分支并发的解码与推测执行,以及在未来处理器中减少误预测代价的断言指令。我们还没看到为降低误预测惩罚大幅缩短的流水线。

在许多CISC计算机中,指令长度解码是一个瓶颈。前向兼容的要求阻止了向RISC指令的迁移。双指令集计算机是一个可能的解决方案,但相当贵。缓存已解码μop在Intel NetBurst架构上不是一个很成功的解决方案,但在Intel的Sandy Bridge及其后继者中要更成功一些。μop缓存的一个劣势是,相比传统的代码缓存,它需要多得多的每指令模面大小(die space)。更关注改进指令长度解码器可能是一个更有效的解决方案。AVX与更新的指令使用新的、包括指令长度信息的VEX编码方案。这开启了解码器对有VEX编码的指令,比最复杂的非VEX编码指令,有更高吞吐率的折衷方案可能性。

缓存μop的另一个方案是在指令缓存中标记指令边界。这解放了指令长度解码的关键瓶颈。大多数AMD处理器使用这个方法,它也在Intel Pentium MMX处理器中。

由于这两家公司间的一个专利共享协议,在Intel与AMD微架构间有一个显著的汇聚。AMD拷贝了Intel的栈引擎与预测间接分支的机制。我们也可以预期某天Intel能与AMD 32字节指令获取速度一较高下。

不幸的是,指令集扩展不总是汇聚的。Intel的SSE4.1及SSE4.1指令集与AMD的SSE4.A及XOP(以前称为SSE5)差异极大,这两组指令集间的交集相当小。Intel从未拷贝现在过时的AMD的3DNow指令集,但他们从AMD拷贝了成功的x64扩展,以及其他几条指令。传统上,AMD拷贝所有Intel指令,但有时落后几年。还好,AMD修改了他们提出的SSE5指令集,使其能与AVX编码方案匹敌(正如我之前辩论的,这样做是明智的)。现在AMD Bulldozer支持Intel的AVX指令集,包括256位YMM向量寄存器。不兼容的融合乘加指令是一个可悲的故事,就像在我博客里讨论那样。幸好,Intel的Haswell与AMD的Piledriver现在都支持FMA3指令。

迁移到3及4个操作数指令对AMD比Intel更容易,因为对许多世代,Intel微架构不允许一个μop有超过两个输入依赖,而AMD从来没有这样的限制。在Haswell中,融合乘加(FMA)指令部分打破了输入依赖的限制。

在CPU流水线中并发程度将不会增长太多,超过每时钟周期4个μop,因为软件中的依赖链可能阻止进一步并发。事实上,我们正看到不断增加的核心数。现在即使低功耗处理器也有多个核心。这对制作多线程应用的软件开发者提出了很高的要求。Intel与AMD都在做混合的解决方案,其中一些或所有执行单元在两个处理器核间共享(Intel术语中的超线程)。

更低的指令时延是达到更高性能的一个方式,我们仅在低功耗处理器中看到。AMD的Bulldozer是第一个将寄存器到寄存器移动翻译为零时延寄存器重命名的处理器,不过Intel很快就跟上了。减少时延的另一个方式是指令融合。

减小时延的另一个方式是指令融合。我们将很可能看到乘法与加法指令的一个自动融合,以及其他常见指令的合并。写到读转发机制也可能被改进以减小时延。

128位XMM寄存器到256位(YMM)的扩展,在2011年1月在Intel Sandy Bridge处理器中,随后在同一年在AMD的Bulldozer中实现。下一步到512位的扩展已经宣布,到1024位的稍后的扩展也被期待。显然,没有超过1024位向量寄存器的计划。XSAVE与XRESOR指令是为未来这些扩展准备的。

有两个版本的指令集用于512位向量。Intel MIC/Xeon Phi协处理器使用称为MVEX的4字节新前缀来增加向量大小,把向量寄存器数加倍到32,并允许指令使用额外的属性,比如掩蔽操作、类型转换、广播、组合、缓存逐出提示、取整模式以及异常抑制。即将来临的AVX-512指令集使用一个几乎完全相同的称为EVEX的前缀。EVEX前缀不允许类型转换与组合,但包括了说明向量大小的比特。MVEX与VEVX指令集彼此不兼容。它们在前缀有一个比特不同,即使对完全相同的指令。MVEX与EVEX指令集都与之前的指令集前向兼容。我预期带有EVEX前缀的AVX-512指令集将是未来处理器的标准,而MVEX将可能难以为继。

很奇怪,MIC/Xeon Phi处理器也支持旧的、看起来过时的x86浮点指令。看起来在可预见的未来,我们无法完全摒弃x87指令,尽管在硬件中实现它们代价很高。

现在x86指令集有远超1000条逻辑上不同的指令,包括用于文本处理、图形、加解密、CRC校验以及复数的专有指令。每个新处理器世代可能会扩充指令集,至少出于市场的原因。我们可能会看到更多应用特定的指令,比如用于加密目的的Galois域代数向量指令。

不过,从技术角度而言,持续增长的指令数可能不是最优的,因为它增加了执行单元的模面大小,因而限制了时钟频率。一个更可行的方案可能是用户可定义指令。我们已经看过结合了专用微处理器核与可编程逻辑的FPGA芯片。在PC处理器上也可以实现一个类似的技术。这样一个处理器将有类似于FPGA的逻辑阵列,可以一个硬件定义语言编程来实现应用特定的微处理器指令。除了代码缓存与数据缓存,每个处理器核将有一个用于硬件定义语言的缓存。当然任务切换的代价将增加,但在核数目增加时,减少任务切换数更容易。

根据摩尔定律,持续递增CPU速度的趋势,在功耗、尺寸与价格方面存在缺点。现在我们看到另一个更小、低功耗处理器,由Intel Atom、VIANano及AMD Bobcat与Jaguar为代表的趋势。这些轻量级处理器与数年前的桌面处理器一样快,但更小、更便宜且功耗低得多。我们将看到这些小处理器在许多之前支付超出所需CPU能力的应用中替换大的高功耗处理器。

24. 文献

当前手册是可从www.agner.org/optimize获取的一系列5本手册中的第三本,如在第1页介绍中提到的。

其他关于微架构的相关文献:

  • Intel 64 and IA-32 Architectures Optimization Reference Manual.
  • Software Optimization Guide for AMD64 Processors.
  • J. L. Hennessy and D. A. Patterson: Computer Architecture: A Quantitative Approach, 3'rd ed. 2002.
  • www.xbitlabs.com
  • www.arstechnica.com
  • www.realworldtech.com
  • www.aceshardware.com
  • www.digit-life.com

你可能感兴趣的:(Agner,Fog编写的优化手册)