《电脑报》

花儿为什么这样红?——K6-3的奥秘

  我们在上期《K6-3踏春而来》一文中看到,K6-3具有良好的性能,这对于Super7用户来说是一大利好消息,因为他们还有机会在不花费大量资金的情况下,进行性能较大提升的升级。AMD的努力是值得称道的。你也许会问,K6-3只不过是在K6-2的基础上集成了256KB二级缓存,为什么它的性能却有如此大幅度的提升呢?OK,你想知道答案吗?请看下文。
    只有K6-3才最后把K6核心的潜力真正发挥出来。Anand的测试告诉我们一些非常有趣的结果(部分测试结果见上期本版),那些高分值的结果看起来好像是K6-3全速二级缓存(Cache)带来的,但这里面有更多的原因。让笔者带你进入K6-3的核心里去看看,你一定会有有趣的发现。
  一、隐藏在高分值后的神秘事实
  首先,让我们看看Winstone′99(一种测试软件)的得分值,对比一下从K6-2 300到K6-3 450,从赛扬300(无Cache)到赛扬450A的性能提升情况(见表1)。

CPU 二级Cache 三级Cache Winstone`99提升
K6-3 450 256KB@450MHz 2MB@100MHz 64%
K6-2 300 2MB@100MHz    
赛扬A 450 128KB@4450MHz   60%
赛扬300 0KB    


  你是不是很惊讶?K6-3 450同K6-2 300的差别比赛扬450A同赛扬300的差别大。不要忘记,赛扬300没有二级Cache,而K6-2却有工作在100MHz下的2MB二级Cache,为什么K6-3性能提升的幅度有这么大呢?
  为了看得更清楚,让我们把主板上的三级Cache(K6-3)和二级Cache(K6-2)关掉(Disable)。正如有人指出:在Winstone '99测试中,带有2MB三级Cache的K6-3比没有三级Cache的快11%。因此,笔者做了快速测试,把K6-2 300的二级Cache关掉。现在来看结果(见表2)。

CPU 二级Cache 三级Cache Winstone`99 Winstone`99提升
K6-3 450 256KB@450MHz 0 20.0(*) 102%
K6-2 300 0 - 9.9
赛扬A 450 128KB@4450MHz 20.6 60%
赛扬300 0KB 12.9


  看到了吗?K6-3的提升幅度比赛扬A450的提升幅度高42%!我并不认为这个结果只是由K6-3的两倍二级Cache带来的。AMD的工程师BOB说:“我们很惊奇地发现在板三级Cache竟然仍有效。”
  二、为什么K6核心对Cache如此渴求
  我想我们有足够的证据说,K6核心(当然包括K6-3)处于极端Cache饥饿状态。为什么?请继续往下读。K6具有一条短且一流的6工位流水线(见图1),下面我只对流水线上最重要的三个工位进行解释:解码(Decode)、流出(Issue)和执行(Execute)阶段。
  1. Post-RISC CPU
  PⅡ和K6都是Post-RISC CPU,它们需将CISC(复杂指令集)X86指令集解码成类RISC(精简指令集)指令,这个工作在解码工位完成。X86指令可以很小(小于8字节),也可以很大(大于16字节),并且这套指令集包含许多程序员从不使用的指令。而RISC指令的大小都是一样的,并且它的指令集小得多。因此,RISC指令更有效且CPU内核(Die)可以做得很小,省下来的空间就可用来做其他事情,如集成二级Cache。
  在流出(Issue)工位,你把类RISC指令放到缓冲器中。当操作数(数据)和执行工位都有空的时候,一个调度器将把缓冲器中的指令移到合适的执行单元中,如整数指令将被移到整数单元,浮点指令被送到浮点单元。这样的缓冲器和调度器是必须具备的,因为现在的CPU能够“乱序”执行指令(即不按程序顺序执行),在Retire(引出)工位时,所有的结果将按原程序的顺序排列。
  在执行工位,所有的指令被执行单元执行。(嗯,就这么简单)
  2.两种CPU核心的比较
  让我们先来比较K6和PⅡ核心的性能。
  PⅡ最多能够对3个X86指令进行解码,比K6核心快50%。但是,K6核心在向执行单元注入的指令比PⅡ快33%,执行单元的指令执行比PⅡ快100%。换句话说,PⅡ核心具有快速的解码器,但执行器相对较慢。这意味着有大量的等待指令和充满内容的缓冲器;而K6有一个较慢的解码器,但它的执行器却很快。因此,同PⅡ相反,等待指令较少且缓冲器很空。也就是说,它的后端(执行)性能优于前端(解码)性能。
  由于K6缓冲器在大部分时间里总是空着,解码器需要总是很忙才能发挥K6的最大性能,如果没有指令或数据供给解码器,CPU只好在一旁“玩弄手指”。想象一下,你碰到这种事该怎样处理呢?答案是只有给解码器不停地输送新指令。而这些指令来自快速的一级Cache或二级Cache,考虑到经常发生Cache未命中的情况(即Cache中没有需要的指令或数据,此时CPU只好到较慢的主内存中查找),只有非常大的而且快速的一级或二级Cache才能让解码器不停地工作。
  这就是为什么K6核心对Cache如此渴求的原因!它执行得如此之快以至于它总是得等待新指令的到来。如果解码器也被迫等待,那整个系统都会停顿下来。
  现在来看PⅡ核心,如果在Cache中没有所需的指令或数据(Cache未命中),并且解码器也有空,这并不意味着有什么太大的损失,因为执行单元正在忙着处理那些在缓冲器中的指令呢。当然,缓冲器里的指令会消耗殆尽,但解码器也会很快恢复工作,重新充满缓冲器。在这里,PⅡ核心对Cache性能的要求不像K6核心那样迫切。
  三、三级Cache的效能
  为什么三级Cache对运行商业应用程序的影响如此突出呢?下面是BOB的回答:“我们还不能完全描述它的效果,但我个人认为,由于二级Cache是4路相关,三级Cache是直接映射,因而它们会趋向覆盖不同的内存区域,结果组合为一个更大的Cache而不是重叠的Cache。”
    不知道什么是“4路相关”和“直接映射”?好的,下面我会解释。
  1.关于Cache
  如果你的系统有1MB三级Cache,但你有64MB或更多内存,你会把哪些内容放到Cache中呢?幸运的是,大部分程序在大部分时间内都经常执行小部分代码。请看下面这个例子:
  for( i=0;i<100;i++ )
  {
  指令A
  ……
  指令E
  }
  编过程序的人都知道什么是“循环”或重复,如果你在第一次循环后把指令A到指令E放到Cache中,Cache命中率就可以达到99%,因为在100次程序循环中,你可以在Cache中99次找到所需指令。这也是为什么需要Cache的原因之一。
  运行商业程序时,你会按下许多按扭,因此触发许多不同的“事件”。换句话说,你需要把大量的指令或数据放在Cache里。在一个字处理软件如WORD里,当拼写检查器工作时,你可能会向上或向下拉动滚动条,当你整理文档格式时,你又可能会时常拉动滚动条。好了,你可能已看到要害了,在拼写检查或格式化文档时,有关滚动的指令最好留在Cache中。但那些指令对一级Cache来说太大了,因此你最好有快速的二级或三级Cache来保持它们。

Instruction Fetch(指令引入)
X86>RISC 86解码
RISC 86 Issue
Execution Stage1(执行工位1)
Execution Stage 2(执行工位2)
Retire(引出)


  2.直接映射Cache和4路相关Cache
  二级Cache最好存储比一级Cache有更多不同的信息,三级Cache最好存储比二级Cache有更多不同的信息,否则,CPU也许每次都要为了同样的数据而检查所有的Cache。这就是为什么三级Cache必须比二级Cache大(大多数设计者认为最好是4倍),二级Cache必须比一级Cache大的原因。
    你怎样才能确信256KB二级Cache里的内容没有被完全拷进1MB三级Cache内呢?OK,你必须为不同的Cache设置不同的规矩。
  首先,Cache被有组织地划分为不同的行和列,就像一个表格。每一行的大小为32字节。这时,1MB三级Cache包含 32768 行 (1024 K / 32)。那么你如何对64MB或更多的主内存进行缓冲呢?你可以把每一行Cache定位分配给每一大块内存。也就是说,每行Cache要分到64MB/ 32768=2KB的内存地址。这种方法的优点在于CPU不需要花太长的时间搜索Cache,此时,每行Cache里有无所需信息是很明确的。不过,这种方法的缺点也很明显。如果我们不停地重复使用同一批指令,而这些指令又占用同一行Cache,那我们就不能把所有的指令放进Cache,因为这行Cache已经满了。最坏的情况是一个重要的指令不断地被另一个重要指令替换(它们共享同行Cache),同时,另一行的一个不太重要的指令又一直呆在Cache里。
  三级Cache的工作方式就是这样,我们称之为“直接映射”。
  “全相关”Cache的工作方式同“直接映射”正相反:内存中任一位置的信息可以被存到Cache中的任一行,这招给了你最大的灵活性。因此,最重要的指令和数据总是可以被安排进Cache中,可以达到高命中率。不过这种技术不太实用,因为CPU将不得不搜索每行Cache来确认所需信息在不在Cache中。
  K6-3的二级Cache工作方式称为“4路相关”。同直接映射比较,你可以保留4行Cache(1套)给大多数内存地址,64MB内存就可以分配给256 KB / 32 / 4 = 2048个4行Cache。也就是说,32KB的内存地址可以共享1套4行Cache。这种方法有一个主要的优点:你能存放最常用指令和数据的可能性比存放在1行Cache中的可能性大大增加了。缺点是,当每次搜索Cache时,你得校验4行Cache,以确认所需信息是否在Cache中。不过,这个缺点影响很小。不管怎样,4路相关Cache的命中率(一般为90%)比直接映射Cache大得多。

本文出自:《电脑报》1999年02月08日第06期