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毫秒