高性能CPU的秘密——Merced CPU篇

Author: 周波 Date: 1999年 第25期 17版

  英特尔推出X86架构已满20年了,同486相比,Pentium向前迈进了一大步,而PⅡ的前进步伐则没有这么大了,X86 CPU的发展似乎已到了尽头。
  英特尔非常清楚,是X86指令集限制了CPU性能的进一步提高,因此,他们正同惠普一道努力开发下一代指令集架构(Instruction Set Architecture ,ISA):EPIC(Explicitly Parallel Instruction Computing,显性并行指令计算)。对英特尔而言,IA-64(英特尔的64位架构)是下一个10到15年的架构。新的ISA将使英特尔摆脱X86架构的限制,从而设计出超越所有现有RISC CPU和X86 CPU的新型处理器。那么EPIC的先进之处在什么地方呢?为什么英特尔会放弃使它成为芯片巨人的X86架构呢?
#1  一、IA-32的问题
  我们知道,工程师可以通过提高每个时钟的指令执行数来提高性能,英特尔新的指令集的首要目的在于,让指令更容易解码,更容易并行执行。这样就可以不受限制地开发新型处理器。
  但是,对工程师而言,兼容8086的X86指令集一直是必须完成的任务。毕竟,兼容前代产品是使英特尔成长壮大起来的关键因素,而且还可以保护用户原先的投资和使用数以百万计应用软件。既然如此,为什么又要放弃整个X86指令集重新开始呢?X86的不足在什么地方?
  (1)可变的指令长度
  X86指令的长度是不定的,而且有几种不同的格式,结果造成X86 CPU的解码工作非常复杂,为了提高CPU的工作频率,不得不延长CPU中的流水线,而过长的流水线在分支预测出错的情况下,又会带来CPU工作停滞时间较长的弊端。
  (2)寄存器的贫乏
  X86指令集架构只有8个通用寄存器,而且实际只能使用6个。这种情况同现代的超标量CPU极不适应,虽然工程师们采用寄存器重命名的技术来弥补这个缺陷,但造成了CPU过于复杂,流水线过长的局面。
  (3)内存访问
  X86指令可访问内存地址,而现代RISC CPU则使用LOAD/STORE模式,只有LOAD和STORE指令才能从内存中读取数据到寄存器,所有其他指令只对寄存器中的操作数计算。在目前CPU的速度是内存速度的5倍或5倍以上的情况下,后一种工作模式才是正途。
  (4)浮点堆栈
  X87 FPU是目前最慢的FPU,主要的原因之一就在于X87指令使用一个操作数堆栈。如果没有足够多的寄存器进行计算,你就不得不使用堆栈来存放数据,这会浪费大量的时间来使用FXCH指令(即把正确的数据放到堆栈的顶部)。
  (5)4GB限制
  这似乎不是问题,但是,在6年前,主流PC只有4MB内存,而目前的绝大部分PC装备了64MB以上的内存,是以前的16倍,所以,在下一个十年,PC内存突破1GB绝对不会令人惊讶,而且目前的大型服务器已经使用了1GB以上的内存,突破4GB内存的情况很快就会出现。
  (6)芯片变大
  所有用于提高X86 CPU性能的方法,如寄存器重命名、巨大的缓冲器、乱序执行、分支预测、X86指令转化等等,都使CPU的芯片面积变得更大,也限制了工作频率的进一步提高,而额外集成的这些晶体管都只是为了解决X86指令的问题。
#1  二、下一代指令集:IA-64
  Merced是第一款使用IA-64的处理器,这款CPU具有64位寻址能力和64位宽的寄存器,所以我们称它为64位CPU。由于具有64位寻址能力,它能够使用1百万TB的地址空间,足以运算企业级任务;64位宽的寄存器可以使Merced达到非常高的精度。
  粗看起来,Merced很像其他的64位RISC CPU:指令的长度是固定的,由一个指令、两个输入和一个输出寄存器组成;指令只对寄存器操作;超标量,具有多个不同的流水线或执行单元,能够并行执行许多指令。那么,Merced的不同点在哪里呢?
  (1)显性并行性
  尽可能并行工作是提高CPU性能的最佳方法,如果你的CPU每个时钟周期可以执行8个指令,而竞争对手的CPU每个时钟周期只能执行4个指令,那么,他只能制造一个时钟频率是2倍于你的CPU,才能在速度上赶上你。
  我们知道,程序分支和指令依赖是造成难以并行执行许多指令的障碍,而Merced采用的方法是让编译器告诉CPU哪些指令可以一起发布并执行。Merced接收来自于编译器的128位包(见^251701a^),每个包含有3个40位指令和1个8位模板。每个指令又由3个7位寄存器地址(即可以使用27=128个寄存器)、一个6位预测寄存器和13位指令代码,其中,最有趣的莫过于模板。
  这个8位模板包含了不同指令间的并行信息,编译器将使用模板告诉CPU,哪些指令可以同时发布。模板也包含了包的结束位,用以告诉CPU这个包是否结束,CPU是否需准备捆绑下两个或更多的包。现在你明白为什么EPIC CPU的马力如此强劲了吧,高端CPU可以一起执行几个包。由于IA-64架构的64个通用寄存器和64个浮点寄存器(编注:原文如此),使CPU可以同时发布许多指令。
  当然,强悍的EPIC CPU也需要一个强悍的编译器,编译器的工作是检查指令依赖情况,把并行指令放在一起,并重新排序,使执行单元可以很顺畅地工作。
  (2)分支预测
  在现代CPU中,分支预测的正确率可以达到90%~95%,虽然看起来还不坏,但当预测出错时,CPU就不得不清洗整条流水线。10%的预测出错率会让CPU损失30%的性能,在流水线越长的情况下,性能损失越严重。而Merced的预测机制,可以摆脱大部分分支情况。首先来看RISC/x86 CPU怎样处理典型的“IF-THEN-ELSE”分支:
   if (i==0)
  instruction 1;
  else
  instruction 2; 
  CPU执行过程如下:
  比较I是否为0;
  如果不相等,则跳到else;
  然后执行指令1;
  跳到NEXT处;
  else:执行指令2;
  NEXT
  在这里,CPU必须判断它去执行ELSE分支呢还是THEN分支。下面再看EPIC CPU的解决方案:
  比较I是否为0;
  开始对指令1解码,设定预测寄存器“P1”的预测位;
  开始对指令2解码,设定预测寄存器“P2”的预测位;
  当I等于0时,寄存器“P1”为真(1),寄存器“P2”为假(0);
  执行所有预测位为真值的指令;
  Merced没有跳跃,它一开始就执行所有的分支指令,它具有64个分支预测寄存器,可以被设为真或假,而每个指令中的6位被分配到单独一个预测寄存器中。就上例来说,如果指令1指派给预测寄存器1,预测位被设为:000001。当变量I等于0时,预测寄存器1被设定为“真”,只有那些指向预测寄存器为“真”的指令结果才会被执行。
  由于所有的分支都能并行执行,Merced所花的时间同只执行单个分支的时间是相同的。其次,你不会再冒预测出错的风险;第三,由于CPU不再跳跃执行,它不会把程序代码分成小块。也就是说,稍前和稍后的程序代码可以打包。Merced能够一起将它们发布,增大并行工作量。这些可以使EPIC CPU避免通常CPU所出现的分支预测40%的出错情况,从而使性能提高10%~15%,特别是在整数代码部分。
  (3)投机装载
  你还记得我们上次所说的3DNow!和SSE的预取指令吗?它可以使CPU把一个确定的指令在需要前的数十个周期放到一级指令Cache中。同此相对应,投机装载是把所需数据提前数十个周期放到一级数据Cache中。这样就可避免Cache未命中情况的发生,如此一来,较慢的内存访问就不再是一个大问题,因为,CPU几乎不再访问内存,它总是可以在一级Cache中找到它需要的东西。
#1  三、小结
  IA-64确实是为提高速度而设计的,使用IA-64指令可以制造一个具有比今天的X86 CPU更多执行单元的CPU,它比X86 CPU能进行多得多的并行处理工作。那么,Merced会在高端市场扼杀其竞争对手吗?它的设计完美无缺吗?我们将拭目以待。