32Bytes instruction fetch(Photo02)

Photo02:要するに今までだと命令フェッチで1回に取り込みきれず、2回に分割して取り込んでいた命令が1回で取り込みやすくなるという話。もっとも現実問題としてx86レベルではそうした命令はそれほど多くなく、むしろSSEのスループット向上が主眼といえるかもしれない。

要するに命令L1キャッシュからの取り込み幅を、従来の16Bytesから倍増したということである。これにより、命令長の長い命令であっても、確実に3命令/cycleが達成できるようになったことになる。まずこれをちょっと確認してみよう。グラフ1~9は、RightMark Memory Analyzer 3.72のDecoder Bandwidthテストの結果である。比較には、

  • Phenom 9900(2.6GHz駆動:Phenomと表記)
  • Core 2 Quad QX6700(2.66GHz駆動:Core 2 Quadと表記)
  • Athlon 64 X2 5000+(2.6GHz駆動:Athlon 64 X2と表記)

の3つを用いてみた。

グラフ1

グラフ2

グラフ3

グラフ4

グラフ5

グラフ6

グラフ7

グラフ8

グラフ9

まずグラフ1~3は単純な命令の場合。命令長1ByteのNOPであれば3Bytes/cycle、2Bytesの命令なら6Bytes/cycleで、これは全プロセッサに共通である。ではもう少し長い命令では? というのがグラフ4~6。

CMP #1:2bytes(cmp eax, eax)
CMP #2:4Bytes(cmp eax, 0x00)
CMP #3:6Bytes(cmp eax, 0x00000000)
CMP #4:6Bytes(cmp eax, 0x0000007f)
CMP #5:6Bytes(cmp eax, 0x00007fff)
CMP #6:6Bytes(cmp eax, 0x7fffffff)

となっている。結果を見ると、CMP #1はピークでも6Bytes/cycle、CMP #2はピークで12Bytes/cycle程度で、これはグラフ4~6に共通だ。ところがCMP #3以降について、Core 2 QuadやAthlon 64 X2はどちらも16Bytes/cycle程度で頭打ちなのに対し、Phenomは18Bytes/cycleに達しており、こうした長い命令であっても3命令/cycleが実現されていることがわかる。

これがもっと顕著なのは。Prefixed CMP(グラフ7~9)である。こちらは6BytesのCMP命令の前に2BytesのPrefixがついたものであり、従って命令長は8Bytesになる。Phenomは流石に24Bytes/cycleにはやや足りない(ピークでも23.22Bytes/cycle)ものの、限りなく3命令/cycleに近いのに対し、Core 2 QuadやAthlon 64 X2では16Bytes/cycleで頭打ちで、実質2命令/cycle止まり。命令フェッチの帯域を32Bytes/Cycleに増やした事で、Phenomではこうした長いx86命令を確実に3命令/cycleで処理する事が可能になった。

また、ちょっと見逃しやすいがL1→L2の帯域も同時に増えた模様だ。例えばグラフ1/3は64KB、グラフ2は32KBを超えたあたりからNOP以外の命令のスループットはガクンと落ちる。これは命令L1キャッシュで収まらなくなるから、であるが、この際にグラフ1とグラフ2はどちらも3.8Bytes/cycle程度の帯域を保っているのに対し、グラフ3は2.9Bytes/cycle程度まで落ちている。つまりL2→デコーダというケースで、Core 2 Quadと同等の帯域を発揮できるようになったという訳だ。

グラフ10

グラフ11

グラフ12

この効果は、単にデコードのバンド幅に留まらない。グラフ10~12はSSE命令を使ってのシーケンシャルなRead/Write/Copyを行った結果であるが、ReadにおいてPhenomはピークで32Bytes/cycleの帯域を持っている事が見て取れる。Athlon 64 X2はたかだか8Bytes/cycleだから、L1キャッシュの帯域は大幅に強化されたことがわかる。もっともグラフ11を見ると判るとおり、Writeに関しては16Bytes/cycle程度でしかなく、要するにReadのみが大幅に強化された形だ。Copyは10Bytes/cycle程度でCore 2にやや遅れを取っているが、これは設計思想の違いと言ってもいいかもしれない。