Hardware 版 (精华区)
发信人: leather (小雨), 信区: Hardware
标 题: 《 高性能CPU的秘密——新技术篇 》
发信站: 紫 丁 香 (Mon Jun 7 08:04:39 1999), 转信
Rise MP6是X86 CPU中第一款具有真正双FPU流水线的CPU,那么,它的性能
比PⅡ好吗?如果你读过有关Rise MP6的评测报告,你就知道,MP6的FPU性能同
使用单条FPU流水线的Pentium MMX差不多。那么,K7的表现又将怎样呢?它的3
条FPU流水线在运行实际程序时只能提高一丁点儿性能吗?
很明显,设计一个能够在每个时钟周期中处理大量指令的CPU是提高CPU性能
的最好方法。在上篇文章(见第18期17版)中我们看到,由于程序分支造成了在同
一时钟周期中难以将许多指令同时发布到各执行单元,解决问题的方法是预测分支
程序的执行情况。不过,除了程序分支外,还有下面3个主要原因使得X86 CPU不
能在每个时钟周期中立即发布大量的指令:
·指令依赖性;
·X86架构只有8个通用寄存器;
·执行单元很忙,所需的执行单元未准备好。
下面一个一个地解释。
一、指令依赖性
所谓“依赖性”就是指令的执行需要前个指令的运算结果。比如程序员经常使
用的分支程序,而CPU设计者就很讨厌这种情况。看下面这个例子:
A=C*2
B=A+2
只要变量A的值还不知道,B=A+2就不能进行运算。也就是说,只要指令1
的结果没有写进寄存器,CPU调度器就不能把指令2发布到执行单元。在上篇文章
中我们看到,程序分支会造成具有较长流水线CPU运行停滞的,解决方法是采用分
支预测;这次我们又看到“依赖性”带来的问题,流水线越长,指令潜伏期也越长,
等待前一指令运算结果的时间也越长,同样会造成CPU运行停滞,比较完美的解决
方法就是采用“乱序执行”和使用更大容量的缓冲器。
二、X86架构的8个通用寄存器
有人大肆抨击Intel已满20岁的X86 ISA(Instruction Set Architecture,
指令集架构)只有8个通用寄存器。他们用这个事实来证明X86 CPU(包括PⅢ、P
Ⅱ、K7等等)是群“恐龙”,已不能同RISC CPU(如Motorola G3和G4, Sun UltraSPARC
Ⅱ等)竞争。
确实,只有8个通用寄存器可用是可笑的。大家都知道,寄存器只是用来暂时
存放指令值的,如果CPU需要把两个值加起来,它需要用1个寄存器来存放运算结
果,用2个寄存器来存放相加的数值。CPU不能直接对存放在主内存中的数值进行
计算,而超标量CPU能并行处理大量的计算,8个寄存器完全不能满足要求,在同
一时钟周期中,如果有3个指令发布,你总共需要3个输出寄存器和6个输入寄存
器。我们该怎么办呢?
聪明的Intel和NexGen的工程师们发现了突破这个限制的方法:“寄存器重命
名”。采用寄存器重命名技术后就可以使用CPU内的秘密寄存器。PⅡ有40个那样
的寄存器,K6有48个,而经典Pentium却没有。可以肯定,K7和Intel的P7也
将拥有大量的寄存器,这样才能够提高每个时钟周期的平均指令执行率。
寄存器重命名技术现在已经深深地扎根于超标量CPU中了。CPU是在解码过程
中对寄存器进行重命名的,解码器把“秘密”的寄存器名字变为“通常”的寄存器
名字,本质上是通过一个表格把X86寄存器重新映射到那些秘密寄存器。因此,尽
管从外面看,现代X86 CPU只有8个通用寄存器,但实际使用到的寄存器远大于这
个数目。虽然重命名和重映射技术似乎很复杂,但却保持了X86 CPU的竞争力。
三、寄存器重命名和乱序执行技术的优点
为了说明寄存器重命名技术和乱序执行技术带来的性能提高,我们模拟一个超
标量CPU执行8个算术指令的例子。假设它在每个时钟周期中能对2个指令解码,
引出计算结果是在指令发布后3个时钟周期发生的。在下表中,读者只需关注“发
布”和“引出”列。
1.按序执行
(1)在第1个时钟周期,两个指令发布:它们互不关联,因此,它们将在3
个时钟周期后(第4个时钟)引出;
(2)在第2个时钟周期,我们首次遇到了“指令依赖”,指令3需要指令2的
结果,此时指令3不能开始发布;
(3)如果是按序执行,指令4、5、6就不能在指令3前发布。只有在第5个
时钟周期时(指令2的结果已得到)才能发布指令3。
(4)在第6个时钟周期有个大问题:我们想把结果写到寄存器R1,但这将改
变指令5的结果。因此,我们只有在R1空闲时(第10个时钟周期)才能发布指令
6。
从表中可以看到,尽管这个CPU是超标量的,每个时钟周期可以对2个指令解
码,但它的性能是很差的。实际解码率(IPC,每个时钟周期的指令执行数)只有
0.53。
2.按序执行和寄存器重命名
如果每次程序所需的寄存器正被使用,我们可以把数据放到另一个“秘密”的
寄存器中。由于在第6个时钟周期将寄存器R1重命名,指令6和指令8不再耽误
CPU的工作。结果是我们能够将IPC提高50%,寄存器重命名技术可以弥补X86处
理器的缺点。
3.乱序执行和寄存器重命名
在按序执行中,一旦我们遇到指令依赖的情况,流水线就会停滞,如果采用乱
序执行,我们就可以跳到下一个非依赖指令并发布它。这样,执行单元就可以总是
处于工作状态,把时间浪费减到最少。乱序执行可以允许我们在发布指令3前发布
指令4~8,而且这些指令的执行结果可以在指令3引出后立即引出(按序引出对X86
CPU来说是必需的),实际解码率又会增加25%。不过PⅡ和K6从乱序执行中得到
的好处有限,因为如果CPU遇到指令依赖情况,它必须找到更多的非依赖指令进行
发布。
WinChip的性能表现让我们看到一个带有大容量一级Cache的按序执行CPU能
够同乱序执行CPU竞争,在时钟周期方面,Cache未命中的代价是非常高昂的。带
有大容量一级Cache的按序执行CPU性能,比只有较小容量Cache乱序执行CPU的
性能要强。
而Rise的工程师在这方面犯了错误,MP6的一级Cache只有16KB,因此Cache
未命中的发生频率比其他CPU高,以致于它很难“喂饱”它的3条流水线。这是很
可惜的事,因为一个按序执行CPU不是太复杂,因此可以做得更小。如果Rise CPU
具有较大的一级Cache和高时钟频率,那么,对于像K6-2那样的乱序执行CPU来
说,Rise CPU是一个凶狠的对手,它具有更好的浮点性能(双FPU流水线),而且
成本也更便宜。集成256KB二级Cache的mP6-Ⅱ或许将纠正这个错误,但它要达
到令人满意的时钟频率。
由于K7采用大容量缓冲,因此它能及时发布足够多的非依赖性指令。大容量
一级Cache、大容量缓冲和乱序执行,使K7的两条FPU流水线比Rise mP6的两条
流水线更容易“喂饱”,效率更高。
四、繁忙的执行单元
为什么现代CPU中的执行单元比解码器数量多?看看实际程序代码,你会注意
到在任何特定的时间段,一个确定的指令类型,如X87浮点指令、3DNow!或整数指
令是具有支配权的。每个执行单元会专门执行确定的指令类型。因此,CPU设计者
必须让解码器“喂饱”执行单元。
K7的三个解码器是通用的,换句话说,大部分时间内每个时钟周期都有3条
指令输出,所以,如果三个指令都是整数指令,K7就得准备3条整数执行单元,
如果执行的都是MMX、3DNow!或X87指令,则还得有3条FPU流水线才能同解码单
元匹配。明白了吗?K7要为每种类型的指令准备3个执行单元才能充分满足解码
单元的要求。当然,K7只有在完美的条件下才能在每个时钟周期发布和执行3个
指令。我们已经知道,由于指令的依赖性和程序分支的存在,CPU要并行地做大量
工作是很困难的。
注意,K7比K6-Ⅲ更合理,K6-Ⅲ有一个浮点单元和两个3DNow!/MMX单元,
但它不能同时发布X87指令和3DNow!指令,因为这两种指令使用同样的寄存器。K7
的多媒体单元则合并了3DNow!、X87和MMX单元。
五、小结
又老又旧的X86架构在今天仍然能同RISC竞争的主要原因是,现代的X86 CPU
都具有先进的RISC核心、寄存器重命名、乱序执行等技术,从而突破了X86架构
的限制。
K7还不是一个“革命者”,它看来是目前进化得最和谐的乱序执行X86 CPU。Intel
的Merced则采用了完全不同的全新设计,这块CPU会碾碎它的对手吗?
--
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: jxjd.hit.edu.cn]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.078毫秒