2024年9月25日发(作者:鲜于泰和)
八戒 前言:
在2006年7月27日,Intel正式发布了它新一代Core 2处理器。基于Conroe核心的Core 2处理器
的性能较上一代处理器有着实质性能的突破。而现在AMD还没有推出新的顶级处理器来与英特尔的Core
2处理器抗争。不幸的是,AMD公司对于已取得极大成功的K8系列高度自信,以至于目前仍没有及时推出
新的应对方案。
根据AMD最近公布的路线图来看,AMD在明年中旬将推出代号为K8L的处理器,而届时Intel的Core
2处理器已经推出一年多时间。K8L原计划将采用四核心设计,在单一晶元上整合4个独立的执行处理核
心,并同时采用共享L3缓存设计,四核心共享一个控制闩门及一个内存控制器。因此,今天我们将为大
家探讨一下K8L微处理器架构的改进之处,看看AMD明年将能为我们带来什么。
一、指令读取
K8处理器在每个时钟周期都将从L1指令缓存中读取已经排列成序的16字节块,同时在这里指令会
被从块中分离出来,然后将指令送到解码单元的通道中。每个时钟周期的16个字节读取比率可以在每个
时钟周期内对三条5个字节长度的指令进行编译处理。然而在某些运算法则中,在一些数据链指令的平
均长度可能要大于5个字节。比如,一些针寄存器与寄存器操作数有关的简单SSE2指令(例如,MOVAPD
XMM0,XMM1)仅仅只有4个字节。
如果一条指令使用间接寄存方式(比如变址寄存器和偏移量一般采用MOVAPD XMM0 [EAX+16]方式),
那么它的指令长度将会增加到6-8字节。 当采用附加寄存器时,在64bit模式下每个指令代码都会增加
一个字节的REX前缀。这样,SSE2指令在64bit模式下的长度可能达到7-9字节。 至于SSE1指令在标量
情况下也会达到7~9个字节,矢量情况下才减少一个字节。
在这种情况下,每周期读取16个字节速度已无法在一个周期内完成3条指令的编译处理,因为此时
矢量SSE和SSE2指令以每2个钟周期3条指令(或每时钟周期1.5条指令)的速率来编译。这样的限制在
K8处理器中还不是太明显,因此它在64bit模式下配备足够的FPUs指令单元。 在未来处理器,处理器
必须保证拥有每个时钟周期至少能够处理3条指令的速率。所以AMD在K8L架构中每个时钟周期读取数据
块大小的能力增加到32个字节,这样的处理能力就目前来说并不是很过分—如果较长指令使用了一些按
近的16字节数据块,那么处理器能获得的指令数量仍然可能达不到每周期处理三个指令的要求。
当32字节数据块中出现5个长指令的情况时,这5个指令可以在一个时钟周期获取。如果指令的长
度出现16字节块的情况下,处理器不可以完成一个时钟周期获取三条指令的任务。
需要说明的是,Conroe处理器的指令缓存仍是采用16字节设计,它的处理原理类似于K8处理器,
因此Conroe处理器可以在指令长度不大于4字节的情况下每个周期完成4个指令解码,而当指令长度超
过4字节就会使得解码指令数下降到3个。为了解决这个问题,英特尔采用了短循环方式,他们在
Conroe处理器中加入了一个特别的64字节内部缓存,缓存可以容纳最大64字节(共4个数据块)的循环,
使得在这样循环中获取的数据可以达到一个周期32个字节。如果循环超过了4个数据块,那么就不能使
用这个缓存了。
如果存在分支指令,那么对于下一个指令数据块的获取就需要使用到分支预测机制。K8处理器的分
支预测是通过一些相对于Conroe显得简单的算法实现的。举个例子来说,K8不能预测到交叉、间接分支
情况(这通常可能对执行多形体代码造成负面影响),对于常规情况下的预测也无法保证准确。因此,AMD
对K8L中的分支预测机制进行了改进。不过AMD目前仍没有透露具体技术细节,我们认为AMD很可能在
K8L中采用增加分支预测表单和计数器的方法,当然分支预测算法也应该有所改进。
二、指令编译
首先需要说明的是,从数据块中得到的X86指令需要被解码成macro-op(宏操作)指令得到执行。每
一个macro-ops指令由2个微操作组成:一个整数或漂浮点运行的操作和一个内存地址存取的操作。 K8
处理器的解码单元可以在区分三种类型的指令:
·DirectPath单指令被硬件解码器的编译成一个macro-op
·DirectPath双指令被硬件解码器编译成两个macro-ops
·VectorPath指令则被芯片整合的微代码引擎ROM解码成3条或更多的macro-ops
附注:DirectPath 和 VectorPath 术语究竟是什么意思。K8的解码器能够通过DirectPath或者
VectorPath来处理x86指令。前者,DirectPath仅处理转换为单个mOPs的x86 指令。其它的指令则由
VectorPath处理,并把它们转换为连续的两个或者更多的mOPs。在这些指令中(包括最复杂的整数分割/
integer division)都使用了Microcode Engine。通过内建的表单,它能够把x86指令放到mOPs序里面。
在K8处理器中,DirectPath和VectorPath指令是不能同时发送的。解码器每个时钟周期以3条
macro-ops的速度发出编译结果。这样,处理器的硬件解码器每个时钟周期能编译3条单指令,1条双指
令+1条单个指令或1.5条双指令(即每两个时钟周期3条双指令)。由于VectorPath指令可以被编译成三
个以上的宏操作,所以就需要超过一个时钟周期才能对这样的指令完成解码工作。解码器每个时钟周期
编译出的macro-ops被统一编成一个组合。每个组合包括2条或1条macro-ops,可能由DirectPath和
VectorPath指令交替操作。 如果一个组合出现指令不足的情况,组合中会加入一个空的宏操作指令进行
补足才一起发送。
来自SSE,SSE2和SSE3指令集的VectorPath指令在K8处理器中被分成一对对的macro-ops来进行
独立处理,比如在64bit执行单元中128bit的SSE寄存器被分成两个64bit的组合。这也就是为什么K8
处理器中处理这样的指令速度是2个时钟周期完成3个指令的原因。未来K8L中的SSE位宽会增加到
128bit,这样就不再需要将指令分成两个部分,从而使得单个128bit macro-ops操作可以达到每个周期
三个指令,速度有了明显提高。这将明显提高VectorPath指令的编译能力—VectorPath指令能每周期以
3条指令的速度编译单条的128bit macro-ops操作。
尽管K8L处理器的解码器每个时钟周期不能编译4-5条指令,略逊色于英特尔的Conroe。但这并不
妨碍程序执行,因为平均每个周期所需执行的指令一般不到3条。 K8处理器一般会把一个X86指令分成
比Conroe处理器更少的macro-ops操作—以32bit方式编译,这样使得K8处理器的解码单元可以达到更
佳的效率。
三、整数指令
编译好的三条macro-ops指令最先被发送到的指令控制单位(ICU),它把他们的信息放进重排缓存中
(ROB),然后转移到调度程序。ROB会自动保存macro-ops的信息并且控制他们的退出顺序。 macro-ops
进入序列后将以三个一组的方式退出,不过每个macro-ops操作都将由调度单元分派到不同执行单元进
行处理。
每个组的macro-ops在调度程序中被分成3个独立序列,每个序列有个8单元(在里面一共有24条
macro-ops),然后被发送到3条对称的整数通道中,每个都有自己独特的队列和一对函数单元。数据准
备好后,调度单元会每个序列中的一个整数操作分派到ALU中,把寻址操作分配给AGU。这样最多会有两
个并行的内存访问。因此,每个周期可以有三个整数操作和2个内存操作得到派送(在这里组合中以
64bit进行读或写)。
整数操作会在序列中根据数据准备情况进行乱序分派,不过从内存中载入的操作会是按照编程顺序
的。当所有线macro-ops 的元素都被执行了,那么队列就会被释放。在执行结果被写到记录文件之后 ,
相同的资源也会被释放。比如:
·add ebx,ecx;
·mov eax,[ebx+10h];快速寻址计算
·mov ecx,[eax+ebx];地址依赖于前一个指令操作
·mov edx,[ebx+24h];这个指令在前面所有指令的地址计算完成之前是不会被执行的
这正是K8处理器的局限性之一。尽管K8每个时钟周期能分派2条读取指令,但效率仍要比Conroe
的存储器低一些—因为Conroe引入了乱序执行机制。在通常情况下,当乱序微处理器重新对指令进行排
序时,它不能在存储前对载入数据进行重新编排,因为它不了解是否会破坏某些数据的位置关联性。但
是在许多情况下,载入数据与之前的存储无关,完全可以提前载入,进而提高效率。
问题在于如何确定哪些可以装载,哪些不可以装载。(注:此功能又被称为内存消歧技术。)值得庆
幸的是,K8L未来也将引入类似的设计来消除这个瓶颈。 不过,目前AMD仍没有透露相关细节,但可以
肯定的读取指令的重排序将不会影响到写入指令,并且这将是某些类型代码出现执行效率下降的原因。
不管怎么说,每个来自ROB的macro-ops组合在执行后将被释放,每个组合中macro-ops操作的排序
和释放可以使得调度程序控制整个资源,提高工作效率。如果三个序列中有一个出现满载情况,那么新
的macro-ops操作组合就不能进入调度程序中。但是,实际操作中这样的情况并不太多,同时也不会对
CPU效率有太大的影响。
除此之外,理论上小组中macro-ops操作到调度单元序列的静态链接有可能降低调度单元的工作效
率,因为一个序列可能含有2个或更多的macro-ops操作等待执行,另一个序列可能一个等待的也没有。
这种情况在实际执行中并不太多,通常在管线中都会有足够多的等待执行指令。
不同于K8,Conroe处理器中针对包括浮点指令在内的所有指令有一个通用序列。整个序列的长度是
32个macro-ops,通用序列理论上可以减少空置的情况及象执行单元之间接合所出现的局限性。同时,
堆栈引擎机制也将帮助处理器减少PUSH、POP、CALL、RET指令之间对于数据的依赖性。不过实际上处理
器很难组织起一个完全使用的系列、将5 条micro-ops操作一起发送,这也就是为什么通用序列通常也
被分成了多个区块的原因。不能很好排序的等待执行指令区块也就是英特尔P6+系列处理器中所出现的排
序混乱问题(乱序)的原因,这会降低处理器的执行效率。而且Conroe处理器对于可以并行读取ROB的寄
存器的数量不能超过3个,这也使得指令流的排序受到了不小的限制。
K8L和Conroe的乱序执行机制存在一些差别,但都可以达到每个时钟周期5条指令的速度,3 ALU+2
MEM。不过两者通常无法在同样的代码上达到最高速度,因此处理器的执行效率需要借助编译器。
四、浮点指令
在K8处理器中浮点指令的调度程序与整数指令调度程序是分开的,并且采用不同操作方式。 调度
程序缓存最多能容纳12组X3条macro-ops (理论上,支持36条浮点指令操作)。 而且,K8还引入可以
将两个不完全的macro-ops操作重新组合成1个完全的组和一个空组的序列合并机制。不同于整数指令执
行单元所采用的对称运算通道,FPU包含3个不同的单元—FADD,FMUL和FMISC(即FSTORE),用来针对浮
点指令的加、乘和辅助的操作,这样调度程序缓存并不会将macro-ops操作在指令组中的位置与特定的
执行单元连接起来。
每个时钟周期,K8中每80bit FPUs能被分派到一次操作。128bit SSE指令被分成两个64bit
macro-ops来编译,然后这些macro-ops在2个时钟周期内被按顺序发送。理论上,每个循环可以最多分
配3个macro-ops操作。不过除了浮点指令以外通常都会带有载入、循环等辅助指令,从而影响了解码速
度、使得理论状态在实际操作中是无法达到的。因此,简单的调度算法并不能达到最优的分派结果,这
样也就会降低执行效率。
由于拥有两条 64bit读取总线,因此K8处理器每个时钟周期能从L1缓存里招收到2次64bit操作数,
这有助于处理器在浮点指令频繁访问缓存中的数据时保持高效的执行率。因为2个并行指令执行就需要4
个操作数,这是K8架构的一个重要的特征(每条指令对应2个操作数。),而在数据流操作中存在许多中
算法,4个操作数中的2个通常都需要从内存中读取数据。
因此,未来K8L将会重点对浮点单元做扩展, 增加一倍的浮点加法器和浮点乘法器, FADD和FMUL
设备将被扩展到128bit,这样在使用矢量SSE指令解码时的浮点性能将增加一倍(注:不仅是分派率加倍,
同样由于简化了macro-ops操作数使得编译及读取效率也增加一倍)。
由于从缓存读取数据的总线也增加一倍,因此K8L可以每个时钟周期从L1缓存中载入两个128位数
据。这种能力使得K8L在一些算法应用中会超过Conroe核心的处理器,因为英特尔的产品只能一次载入
一个128位数据。根据目前透露出来的信息,K8L的FMISC(FSTORE)设备将仍然保持64bit。由于从128
位SSE寄存器写入到存储器是在FMISC单元上执行的,那么这将会在计算中成为一个瓶颈,使得处理器无
法每个周期完成一个128位的数据写入,AMD这样的设计显然有些不合逻辑。
所以,我们认为这可以是AMD公布的资料中存在错误—FMISC单元应该可以在每一个周期内完成128
位数据的写入,或者K8L是通过2个FMISC单元来完成以上工作。
英特尔的Conroe和AMD的K8处理器不同,Conroe中使用了通用序列完成整数和浮点指令。除此以
外,整数和浮点指令的分派端口是组合在一起的,这样也就会使得某些整数和浮点指令无法组合在一起。
Conroe另一个限制则是采用X87命令(没有进行SSE优化)的浮点算法会在FMUL的分派速度上减慢,比通
常操作慢了2倍。
而K8L拥有更宽的执行单元,同时该处理器还将在FADD、FMUL块中拥有更多的整数单元负责处理
SSE2指令。使用SSE2指令的整数应用将在K8L处理器上更快的执行。K8L处理器中的FPU执行效率将会
很高,在一些情况下(可以每个周期读取2个128位数据)会比英特尔的Conroe高很多。
但凡事都有利弊的两面性,K8L对浮点单元做扩展也将带来一些问题。那就是K8L将会面临主频难以
提升的问题—K8L引入浮点扩展后, 将抵消65nm工艺的利处, 主频难以依靠65nm工艺大幅提高。因此,
即便引入先进的65nm制程,早期的K8L在主频上将低于Conroe, 在效率上也不是同频Conroe的对手。
K8L唯一的最优竞争力的地方是x87浮点应用,但是SSE/2/3浮点应用,弱于同频Conroe,K8L浮点计算
峰值也仅能提高50%,游戏性能也将继续和K8一样会弱于同频Conroe。
五、缓存及内存子系统
K8中L1缓存是一分为二的:指令和数据缓存各为64KB。每个缓存都是双路并联方式,长度都是64
个字节。这低的组合是由于核心每个时钟周期内只能从缓存进行两次读取操作。因此,需要通过增加容
量(64KB)来弥补不足;在不方便运算的地方,有效缓存的容量应该接近于采用4路并列的32KB缓存。在
对较大的L1缓存每个周期进行两次读取操作中,有顺序访问的算法看起来要更好一些。
L2缓存(相对称的L1缓存配置)是独立的:在L1和L2缓存的数据是不重复的。 L1和L2缓存通过2
条单向性的总线来交换数据(一条从L1连接到L2,另一条从L2连接到L1),每条总线拥有64bit或8个
字节(数量为6条)的带宽。
在这里,处理器每个时钟周期以8个字节的低速率从L2缓存收到数据(8个时钟转换成一个64-byte
的数据链)。因此,数据传输过程中存在很高的延迟,特别是当L2缓存中存在2个或是更多的数据链需要
同时访问的时候。 针对这个问题,K8通过提高缓存采样命中率来弥补高延迟的不足,毕竟L2缓存是采
用16路并联方式,同时L2缓存的容量也相当的大(由于独立的设计)。
我们都知道,AMD在K8内核中整合了一个内存控制器。 数据通过闩门从内存控制器输出,并绕过L2
缓存、直接输送到L1缓存中。 这样的设计有效降低了系统内存中数据传送的延迟。L2缓存只会得到那
些在L1缓存中暂时用不到而需要储存的数据。上面我们已经提到,K8L处理器的L1缓存每个时钟周期最
高能进行两次128bit的读取或一次读取及一次写入。
很不幸的是,AMD并没有告诉我们L1、L2连接总线的设计或带宽会不会改变。但是我们希望总线带
宽度至少增加2倍,不然内部缓存总线的太低的话会影响到CPU执行浮点指令流时的性能。L1缓存的并
联并不会增加,所以我们应该不会看到K8L处理器在这个方面的应用上有明显的性能提高。
K8L还将采用共享L3缓存设计(4个或更少的核心之间共享),容量在2MB以上。L3缓存也很可能采
用独立方式,象L2缓存一样。通过一个增强的闩门,L3缓存可以使得相近核心之间交换修改后数据的速
度加快,避免出现使用内存总线所带来性能下降的问题(像K8处理器中那样)。英特尔在Conroe处理器中
通过两个核心共享L2缓存解决了这个问题,4核心的K8L处理器在内部核心数据传输性能上会比较接近
Conroe。
值得注意的是,Conroe核心的处理器有一个值得称道的缓存系统,包括一个32KB的L1缓存(8路并
联)和一个2~4MB的L2缓存(16路并联),两者之间采用全速的256位总线互联。Conroe处理器同时具有
较高效率的预取单元,可以主动从系统内存、L2缓存中载入数据到L1缓存中。这样的增强缓存系统也使
得Conroe处理器在SPEC INT测试中有40%以上的性能提升(相对于Yonah核心,在一些子测试中)。
不过,从目前显示的情况来看,AMD的K8L将不能主动将L2中的数据预存到L1缓存中去,同时也不
会在核心中加入高效预取单元。这意味着如果K8核心的缓存子系统不足没有在K8L处理器中得到有效解
决,那么K8L可能无法充分展示它的性能潜力,甚至在竞争中可能会败于Conroe。
除以上创新之外, K8L的内存子系统还可以通过改进对即将来临的DDR3 SDRAM和FB-DIMM提供支持。
同时K8L架构还将采用模块化设计,从三级缓存到内存控制器,K8L核心每个组件都采用模块化设计,
AMD表示,K8L这种组件模块化设计将带来更强劲的性能和更优化的连接界面。
此外,K8L还将采用新一代HyperTransort传输协议,双向传输带宽将提升至5.2GB/s。以基于K8L
架构的Opteron处理器为例,它将集成4条16-bit HyperTransport-3连接,并且可以转变成8条8-bit
HyperTransport连接,以达到8个处理器插座达到最大32个完全互连核心的目的,即非机械性连接。但
是这些改进将对台式电脑的性能提升并没有多大影响。
结论:
作为K8架构的最新之作,我们看到K8L较上一代产品有了不少的改进及提高,比如指令从16bit增
加到32bit、引入更为完善的分支预测算法、类似于Conroe的乱序指令读取机制等等,这些改进都将可
以消除处理器在整数运算方面的瓶颈,提升整体运算的性能。同时,对于SSE指令集的扩展也将使K8L处
理器应付大型SSE浮点运算、整数运算等方面的性能有着明显增强,K8L甚至有可能在这个方面超越英特
尔的Conroe。
不过K8L处理器无法实现每个时钟周期4个指令同时解码及消除操作会使得处理器在整数运算应用中
面临一些问题。当然,这样的问题在多数情况下都不会造成太大影响,除了某些情况下才会造成性能明
显降低的问题。
当然,作为K8架构的延续,AMD在K8L之上还需要花费相当的心机。比如AMD需要考虑如何才能应
付来自英特尔的竞争压力,如何在发布K8L之时击败已经发布1年之久、步入成熟时期的Conroe处理器、
如何超越英特尔等等问题。这也正是众多AMD粉丝们所迫切关注的。