Trace Cache

    说了AMD的Victim Cache,不能不说Intel的Trace Cache。Trace Cache其实也是非常有创意的。由于AMD的强力竞争,Intel必须要做出主频非常高的CPU来。而PIII的主频极限在1GHz左右,是不可能和AMD的Athlon长久僵持下去的。所以Intel开发的P4必须要达到非常高的可以吓人的主频。而要提高主频,CPU的流水线深度就必须增加,毕竟Intel的电子技术不可能比AMD领先很多。事实上,由于x86指令集的复杂特性,x86系列CPU的流水线中相当一部分的深度(大约有一半)是耗费在指令译码上的。所有这些问题在顺序执行程序中都不成为问题,流水线就是为这设计的。但是条件转移指令却造成了大麻烦。由于条件转移指令有2个分支,而究竟应该执行哪个分支,却要等条件转移指令执行完以后才能知道。而在指令进入流水线到得到执行结果之间有很多个周期,在这期间用哪个分支的指令去填满流水线就成了问题。具体的情况,请参看《计算机原理实验》课的讲义。另外,由于条件转移指令的出现概率很大(静态10%,动态15%,相当于每执行6~7条指令就有一条条件转移!!),使这个问题必须解决,才能使流水线有实际的性能提升。而事实上,这个问题也有相对较好的解决方案,就是分支预测。具体情况也请参考《计算机原理实验》课的讲义。所有这些技术,在现有CPU中都得到了应用。

    所有的情况看起来都很完美:问题得到了解决,性能得到了提升。但电子技术发展实在太快,任何人都难以预料。AMD做了一件惊天动地的事,就是做出了Thunderbird核心的Athlon,不仅各种测试指标比PIII好,而且主频还比PIII高。Intel措手不及,仓促推出PIII 1.13GHz,但是PIII核心毕竟能力有限,不得不尽数收回,Intel可谓吃了大亏。在这种情况下,Intel必须推出一款至少看起来非常快的CPU来和AMD竞争。而且,Intel的时间非常有限。由于当时CPU主频已经跨越1GHz,根据摩尔率,2~3GHz的CPU出现的时间已经不远了,Intel为了在主频上取得竞争优势,就必须瞄准2~5GHz这样的档次。为了要达到如此高的主频,流水线加深就是必然的了。而针对x86指令集来说,流水线需要加深的部分主要集中在译码部件。事实上,象ALU这样的部件是跨越做到很高的主频的。而此时,条件转移指令又出来捣乱了。虽然可以用分支预测,但是毕竟只是预测,不可能做到100%的准确。对分支指令来说,预测的准确率达到一个程度之后就很难再提高了。当然,分支预测失败在流水线浅的CPU上是问题不大的,因为在得出结果前没有多少指令进入流水线,刷新一下也不费事。但P4就不同了,其20级流水线,且大部分是在指令译码部分,一次刷新就把所有的性能都刷掉了。所以,分支预测的问题还要用更强有力的手段来处理。

    为了解决这个问题,还是要先看一下影响性能的各个因素。我们关心的不是直接的分支预测准确率这样的指标,而是实际的程序执行速度。前面已经讨论过,流水线可以很容易对付顺序执行,主要的问题是分支。所以,我们看一下在有分支预测功能的CPU上,分支指令的“视”执行速度公式:

    ExecTime = PredictTime + FailRate×FailPenalty

其中ExecTime表示平均的执行速度,PredictTime表示在预测成功情况下分支指令的执行速度,FailRate是预测失败的概率,FailPenalty是分支预测失败时需要多少时间恢复流水线。可见,右边的3个量任意一个的减少都可以提升性能。首先看FailRate,前面已经说过FailRate在达到一定程度后很难再减少,所以其提升能力有限,不过Intel还是在这方面做了一些工作,包括更深的BTB等等。

    当然,光靠这一点是不能解决问题的,还必须要有其它的措施。另外2个参数,PredictTime在PIII上是1,事实上可以通过一些技术减少到0(所谓的0周期条件转移,请参考《计算机原理实验》课讲义),但是不可能再少了,而且其减少的量也不大。后面我们也要分析,Intel的Trace Cache可以把这个参数减少到0。

    前2个参数的改进都无法达到目的,就只剩下最后一个参数了。我们前面说过,流水线加深会导致分支预测失败的附加开销增加,也就是FailPenalty增加。所以,最直接的优化方法是减少流水线深度。但是,要提高主频,就必须要加深流水线深度。这似乎是一个死循环。

    其实不然,要解开这个死节也是有一些办法的。一种“傻、大、粗”的方法是把2个可能的分支都放到流水线中执行,等分支确定以后,只要把不该执行的一半去除就可以了,另一半是正确的。对超标量CPU来说,这是可以实现的,而且不复杂(似乎IBM的PowerPC是采用这样的方案:IBM一贯的风格就是傻大粗,不过没有查阅过详细的资料,不能确定)。这样的实现缺点也是显然的,2个分支都要进入CPU,浪费的资源也比较多。

    要解决问题首先就要研究问题。对x86指令集,译码需要的时间是很长的,流水线的大部分工作是进行指令译码。如果我们可以把这部分时间坎掉,其实流水线就不深了。所以,在执行时不需要指令译码是最理想的方案。

    执行时不译码并不等于是要求直接执行x86指令,事实上这样的要求是不可能在高速CPU中采用的。要解决这个问题还要看程序的特点。对任何程序,几乎都可以说其执行时间绝大部分是在循环体内的。因为现在的CPU非常快,即使只1秒时间,也可以执行1G条左右的指令,如果没有循环,最简单的单字节指令也要有1GB大小,而我们的可执行文件大的也不过1~2MB,也就是说程序中平均每条指令要执行1000~1000000次。这是一个非常好的特点:如果这条指令要执行1000次,那我们只译码一次,而执行它1000次,则把一次译码的时间分摊到1000次执行,基本上可以忽略,所以这种方案可以叫做“不译码”的。

    这样,处理方法就出来了:我们先把整个程序都译码放到一个缓冲区中,然后在这个缓冲区上执行,由于此时分支的2个后继都在缓冲区中,即使发生预测失败,也只需要刷新流水线的执行部件内的错误指令,译码部件的长流水线就从FailPenalty中砍调了,从而大大降低了FailPenalty。

    上面所说的要把整个程序都译码放到一个缓冲区中其实是没有必要的,在这方面,传统的缓存理论可以解决这个问题,所以,我们要做的是一个缓冲译码后的指令的缓存,在这个缓存的读端口上加一个译码部件就可以了,其缓冲的内容是虚的。这就是Intel的Trace Cache。

    Trace Cache还有一个好处,就是0周期条件转移。因为分支预测成功时,将从Trace Cache中加载译码后的指令(Intel称作微操作,uOP),这些指令的译码被消除了,节约了时间,相当于分支指令没有用时间。而分支指令是很多的(15%),加上强有力的分支预测,对提高程序性能应该说是非常有帮助的。

    Trace Cache还可以消除指令预取对循环和函数起始地址的要求。由于指令预取总是在16字节边界,所以要充分利用指令预取的缓冲区,函数和循环的入口地址应该对齐到16字节边界。而Trace Cache中的微操作根本不需要译码,所以不存在指令预取缓冲区,也没有这个问题。

    Trace Cache也可以解决指令译码配对的问题。由于x86指令异常复杂,不可能同时集成多个全功能的指令译码部件,所以在PIII和Athlon中都对简单指令和复杂指令分别对待,这就要求指令按一定的模式出现,才能让所有的译码部件能够并行工作。而Trace Cache中的微操作不需要译码,自然不存在如何配对的问题。

    看来Trace Cache简直是太美好了,美得就象天使一样。可是......脸很天使,身材也很天使......

    译码后的微操作有一个特点,就是很长。PIII的微操作长度,按Intel的说法是72位,合9字节。在P4的Trace Cache中,我估计不会用这么长的微操作,必须进行压缩。但是,由于x86指令集有32位常数,要获得足够的执行效率,微操作中必须要能够放得下,所以微操作长度不能少于32。虽然可以象MIPS一样把常数分解成2个16位,但那样就会使微操作数量大大增加,执行部件的负担会增加很多。所以,我们不妨设P4的微操作长度为48(是否能压缩到这个长度还是个问题)位,合6字节。于是,12K的Trace Cache合12×6=72KB!!??要知道Athlon的L1 I-Cache才64KB,也就是说P4的Trace Cache消耗的晶体管数比Athlon的L1 I-Cache还要多了很多,其身材......是足够天使了。虽然Intel的电子技术先进,但也经不起这样的浪费啊,所以不得不砍去其它的一些部件,于是L1 D-Cache由16KB砍成了8KB,MMX运算单元由2个砍成了1个,指令译码单元由3个砍成了1个,地址生成单元被砍没了,单周期、全流水的MMX/SSE运算单元被砍成了2周期、差不多不流水的了,L2的块大小由32字节砍成了128字节......再砍就不是CPU了!!所以,万般无赖之下,P4不得不开足了马力,功率直冲70瓦,大有赶超Athlon之势。

    总的来说,Trace Cache是一个非常先进的设计,先进到不适合在现有的电子技术上使用。在以后集成1G个晶体管已经不成为问题的时候,不用Trace Cache做CPU的公司才是脑子有问题。但是现在的电子技术似乎还不能支持如此先进的设计,Intel可以说是太前卫了。

    由于P4被砍去的那些部件,使P4在执行效率上远不如PIII是必然的了。比如MMX运算,P4上大部分MMX指令要2个周期才能处理一条(2周期/条的产出),延迟是2~6周期,而PIII有2个MMX单元,每个单元每个周期都可以处理一条MMX指令,且大部分指令的延迟仅1周期,即使是乘法指令也才3周期的延迟,从这些数据不难看出,P4执行MMX指令的效率可能不如同主频PIII的1/4。即使用SSE2指令,由于巨大的延迟,其效率也令人怀疑。所以,某些测试PIII大幅度超越P4是很正常的。所以,要配Intel的CPU,就配Tulatin核心的塞羊,如果有公司生产支持新的移动PIII的主板,肯定会卖得很火。


Leading Cloud Surveillance, Recording and Storage service; IP camera live viewing

Leading Enterprise Cloud IT Service; cloud file server, FTP Hosting, Online Storage, Backup and Sharing

Powered by FirstCloudIT.com, a division of DriveHQ, the leading Cloud IT and Cloud Surveillance Service provider since 2003.