METech 版 (精华区)
发信人: alphame (糊涂), 信区: METech
标 题: [转载] 高性能CPU的秘密—新技术篇
发信站: 哈工大紫丁香 (Tue Apr 27 17:34:34 2004), 站内信件
【 以下文字转载自 COA 讨论区 】
【 原文由 Lerry 所发表 】
高性能CPU的秘密—新技术篇
● Johan De Gelas
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个通用寄存器;
·执行单元很忙,所需的执行单元未准备好。
下面一个一个地解释。
一、指令依赖性
所谓“依赖性”就是指令的执行需要前个指令的运算结果。比如程序员经J褂玫姆
种С绦颍鳦PU设计者就很讨厌这种情况。看下面这个例子:
A=C*2
B=A+2
只要变量A的值还不知道,B=A+2就不能进行运算。也就是说,只要指令1的结果没有
写进寄存器,CPU调度器就不能把指令2发布到执行单元。在上篇文章中我们看到,程序
分支会造成具有较长流水线CPU运行停滞的,解决方法是采用分支预测;这次我们又看到
“依赖性”带来的问题,流水线越长,指令潜伏期也越长,等待前一指令运算结果的时
间也越长,同样会造成CPU运行停滞,比较完美的解决方法就是采用“乱序执行”和使用
更大容量的缓冲器。
二、X86架构的8个通用寄存器
有人大肆抨击Intel已满20岁的X86指令集架构只有8个通用寄存器。他们用这个事实
来证明X86 CPU(包括PⅢ、PⅡ、K7等等)是群“恐龙”,已不能同RISC CPU(如Motor
ola 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未命中的代价是非常高昂的。带有大容量一级Ca
che的按序执行CPU性能,比只有较小容量Cache乱序执行CPU的性能要强。
而Rise的工程师在这方面犯了错误,MP6的一级Cache只有16KB,因此Cache未命中的
发生频率比其他CPU高,以致于它很难“喂饱”它的3条流水线。这是很可惜的事,因为
一个按序执行CPU不是太复杂,因此可以做得更小。如果Rise CPU具有较大的一级Cache
和高时钟频率,那么,对于像K6-2那样的乱序执行CPU来说,Rise CPU是一个凶狠的对
手,它具有更好的浮点性能(双FPU流水线),而且成本也更便宜。集成256KB二级Cache的
mP6-Ⅱ或许将纠正这个错误,但它要达到令人满意的时钟频率。
由于K7采用大容量缓冲,因此它能及时发布足够多的非依赖性指令。大容量一级Ca
che、大容量缓冲和乱序执行,使K7的两条FPU流水线比Rise mP6的两条流水线更容易“
喂饱”,效率更高。
四、繁忙的执行单元
为什么现代CPU中的执行单元比解码器数量多?看看实际程序代码,你会注意到在任
何特定的时间段,一个确定的指令类型,如X87浮点指令、3DNow!或整数指令是具有支配
权的。每个执行单元会专门执行确定的指令类型。因此,CPU设计者必须让解码器“喂饱
”执行单元。
K7的三个解码器是通用的,换句话说,大部分时间内每个时钟周期都有3条指令输出
,所以,如果三个指令都是整数指令,K7就得准备3条整数执行单元,如果执行的都是M
MX、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会碾碎它的对手吗?
--
11、对书呆子好一点,因为你未来很可能就为他们中的一个工作。
——比尔·盖茨
※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 222.32.3.181]
--
※ 来源:.哈工大紫丁香 bbs.hit.edu.cn [FROM: 202.105.138.147]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.353毫秒