GMPを使った円周率計算は、なぜAMDの方がIntelより速いのか?

命令の重要度が意図的かつ、K8とP6Fの比較がおおさっぱであるとのご指摘があ りました。またadc命令のファクタを見落としているとのご指摘もありました。 それを加味した文章に変更しました。
最近、GMPを使った円周率計算プログラムのベンチマークデータを送ってくれる 人も増え、それにつれてあちこちで参照されるようになった。しかし、見てい るとかなりの人が、雑誌などのベンチマークのIntel優勢の傾向と違いAMDの方 が速いという結果に首をひねっている。 理由は簡単である。GMPは数多くのCPUアーキテクチャーで動作するよう汎用的 な命令を前提にプログラムが作られていることと、数百万桁の円周率計算をす るプログラムの性質上、メモリとプロセッサ間でのデータ転送が大量に発生す ることが、AMDプロセッサに大きく有利に働いているからである。

さらに詳しく説明

そこで考察をしてみたい。 なお以下の議論は下記のレポートを参考にしている。
  • http://swox.com/doc/x86-timing.pdf

    AMD Athlon 64 vs Pentium 4 Prescott

    クロックあたりの処理性能を比較してみる。単純な命令add/sub、and/or/xor、 inc/decもPentium 4 Prescott (以下P4F4)よりAMD Athlon 64(以下K8)とInetl Core 2 が速い。つまり、もし実行コードがこのような単純な命令中心の処理で あっても、(シングルスレッドを前提にしても)クロック数をあげなけれP4F4が 性能よくなることはない。つまりクロック数をあげることで処理能力をあげる という必要あるという一般的な認識の通りである。

    またP4F4は、命令コードの違いで極端に処理性能が違う。乗算命令であるimul のレイテンシーはP6FとK8の方がP4F4の2倍ぐらい性能がいい。除算命令divも同 様な傾向を示し、またSSEもMMXで行っても同様の傾向を示す。またキャリーフ ラグを使う加算命令adcに至ってはレイテンシーで10倍程、スループットで7倍 程と極端な差がある。

    GMPライブラリの中では乗算と除算命令、またキャリー加算も大量に使っている。 なぜならばその方がすなおな実装だからである。もしP4F4だけをターゲットし ているならば、乗算や除算命令を使わずインプリメントすると高速になる。し かし、それは余計な処理量を必要とすることであり他のプロセッサでは遅くな るだろう。

    P4F4はそれ以外にも64bitモードで右シフト命令shr/sarが急に低速になる。32 ビットの場合2,.5-2.7クロック程度なものが、64ビットモードとなると8クロッ ク程度になる。ところが左シフトは影響せず2.7-2.5とかわらない。

    これからわかるようにP4F4では高速にしようとすると利用できる命令がかなり 制約される。かなり癖のあるプロセッサだ。

    結論: 命令レベルでみた場合Pentium 4 Prescottは乗算、 除算、キャリー加算、64ビットの右シフトをすると極端にパフォーマンスが 低下する。非常に癖があるので、特別なチューンをしない限り性能は発揮で きない。また、そのチューンは他のCPUアーキテクチャーでは不利に働く。

    AMD Athlon 64 vs Intel Core 2

    命令レベルで見た場合、add/sub、and/or/xor、inc/dec といった基本的な命令 は互角である。以下はレイテンシーは同じであるが、クロックあたりのスルー プットでいえばshl/shrといったシフト命令系では多くの場合AMD Athlon 64(K8)が1.5倍速いが、shld/shrはIntel Core 2(P6F)が3倍速い。

    GMPに関連する部分では、K8とP6Fのimulの差はさほど大きくはないが、多く使 われるadc命令はP6FよりK8の方が2倍強速い。この点はK8がたいへん有利である。

    命令レベルでF6Fを考えるとadc命令の影響でK8がそこそこ有利か、という所で ある[注]。しかし寄せられたデータを見るとK8の方がかなり有利に処理ができ ている。adc命令以外の影響として、何百万桁の円周率を計算しようとするとメ モリとCPU間で大量のデータ転送が発生する性質が効いているのだろう。 HyperTransportの性能であるが理論値でAthlon 64 は20.8GB/s、Phenomは 27.2GB/sである。Intelの理論値は8.5GB/s もしくは10.7GB/sである。もちろん、 理論値の上限を使えるわけではないが、それを勘案しても1.5-2倍程度の差があ る。

    [注] 2008年7月2日以降のpi_quick_startは、下位ライブラリレベルでAMD Athlon 64系 と Intel Core 2系とは違う(アセンブラレベルの)コードで動いて いる。よって2008年7月2日以降の結果を使っては、ここで述べているような同 一コード前提の比較はできないので注意すること。

    全体を見た場合命令ではK8、P6Fとほぼ互角であるにもかかわらず、かつ、メモ リバンド幅の大きいK8にもかかわらず、大量にデータを処理するはずのエンコー ディングでは、なぜK8 が不利なのだろうか説明できない。これはエンコーディ ングの処理ではデータに局所性があるからなのだろう。別のいい方をすると処 理が複雑なので、少量のデータに対して大量の命令が消費されるのだろう。少 量のデータに対して大量の命令が消費するのは、たしかにCPU内部のベンチマー クには向くといえる。ただし、そのベンチマークの結果をいくらもってこよう とも、GMPライブラリを使って数百万桁の円周率を計算するのを予測することは できない。プログラムの性質が違うからである。64ビットモードになると、単 位クロックあたりの処理データ量は単純にいえば32ビットモードの倍になる。 64ビットモードでは、さらにメモリバンド幅がボトルネック要因になり差が開 くと考えられる。

    結論: 命令レベルではK8とP6Fの性能は全体的に互角である。 しかし、GMPではadc命令の差によりK8が有利。またメモリ/CPU間で大量のメモ リ転送が発生するようなプログラムでは、メモリバンド幅が大きいK8が有利で ある。

    まとめ

  • Intel Pentium 4 Prescottは、あまりにも偏った性質を持つプロセッサで ある。汎用なソフトウェアには、とてもじゃないが使えない。

  • Intel Core 2は、命令レベルでは性能が良い。癖のないよくできたプ ロセッサである。ただしメモリとプロセッサ間のメモリバンド幅がネックにな るようなプログラムには向かない。

  • Athlon 64も命令レベルでは大体Intel Core 2と互角。またadc命令が 速いためGMPでは有利に作用している。メモリバンド幅が必要なプログラムでは Intel Core 2 よりも有利である。

    ハイパフォーマンスコンピューティングでは、メモリバンド幅というのは非常 にクリティカルな部分であるので、ここではAthlon 64系のCPUを使うことに なるだろう。しかしデスクトップで事務処理をするようなレベルであればCore 2系とAthlon 64系のパフォーマンスの差を議論するのは意味がないように思 われる。またWeb サーバのようなものメモリバンド幅はあまり関係ないので同 様である。

    なお、最後にあらためて確認しておきたいが、GMPで円周率300万桁を求めるよ うなプログラムは、ハイパフォーマンスコンピューティングの参考のひとつと して使うのは意味があると考えるが、一般ユーザのデスクトップパソコンを考 慮する指標に使うのはあまり適切とはいえない。

    追加

    K8 分岐予測性能は優れていることと、L1iのサイズがP6Fの2倍あることはな んらかの影響をあたえているとは思われるが、適切な参考資料が見当たらな いので考察にまでは至らなかった。

    変更メモ

    あちこちから指摘をいただきありがとうございました。

  • Intel Core 2をひいきにした書き方だという声もあったので、なるべく公 平な表現にしてみました。

  • adc命令に言及していなかったのは不備でした。

  • mul命令たしかに遅いですが実際のGMPのコード中ではimul命令の方が多く、 そんなに大きなファクタとはならないと考えます。
    目次へ

    すずきひろのぶ Hironobu SUZUKI < hironobu -at- h2np -dot- net >

    $Id: amd_vs_intel.html,v 1.4 2008/07/02 13:01:48 hironobu Exp hironobu $