AMD党を離党した件 - Core i7とPhenom X4をサーバアプリケーションで比較
K6以来ずっとAMD党だったのだけれど、サーバにCore i7 920を導入しちゃったので、Phenom X4 9350eと比較する形で、簡単にサーバアプリケーション(ていうかLang-8)のベンチマークをとってみました。
Phenom X4と、Core i7は、どちらもQuad Coreなので、コアが4つ入っています。しかしCore i7では、Prescott時代に導入されていたHyperThreading(HT, SMT)が復活しているので、4*2で8スレッドの並列実行が可能になっています。ゲームやオフィスアプリでのCore i7のベンチ結果は随所で見かけるけれども(そしてHTの性能アップ寄与についての結果は大体芳しくない)、マルチスレッドがフルにスケールするサーバ系アプリケーションで、HTの効果がどれほどなのか気になるところ。というわけで、HTをOnにしたとき、Offにしたときの双方の結果をとってあります。
対象マシン
Core i7機
CPU:Core i7 920 (実クロック 2.67GHz、OC無し)
チップセット:X58
メモリ:DDR3-PC10600 1GB×3枚(TripleChannel)
NIC:オンボードの蟹(Realtek 8111C)
OS:Fedora10(Linux foo.lang-8.local 2.6.27.5-117.fc10.i686 #1 SMP Tue Nov 18 12:19:59 EST 2008 i686 i686 i386 GNU/Linux)
Phenom X4機
CPU:Phenom X4 9350e(実クロック 2.00GHz)
チップセット:nVidia NFP3400
メモリ:DDR2-PC6400 2GB×2枚(DualChannel)
NIC:オンボードNC105i
OS:Fedora10(Linux bar.lang-8.local 2.6.27.5-117.fc10.i686.PAE #1 SMP Tue Nov 18 12:08:10 EST 2008 i686 athlon i386 GNU/Linux)
Core i7機のNICが蟹だったり、Phenom機のLinuxカーネルがPAEモードだったりと、CPU周り以外にもパフォーマンスに影響を与えそうな細かい差異は色々とあるのですが。
測定方法
Railsで書いたLang-8をMongrelにデプロイし、Mongrelインスタンスを16個起動した上で、一番負荷が大きいページURLをApacheBenchで叩き続ける。以下のようなシェルスクリプトを用いて、ApacheBenchのConcurrency Level(同時接続数)を、1〜32の範囲で変化させてトータルのスループット(requests/sec)を比較。Railsのバージョンは2.3.2を使用しており、Ruby1.8.6 (CRuby)上で動かしています。
for i in `seq 1 32`;
do
ab -n 160 -c $i http://balancer.lang-8.local/
done
前提として、今回abベンチマークの対象にしたページでは、CPUリソースを馬鹿食いするActiveResource(詳細はこちら)を多用しているため、負荷の種類としては、ほぼ完全にCPUバウンドです。また同一ページを繰り返し表示させているだけなので、アプリケーションが内部で発生させるIOは、ActiveResourceのレスポンスをキャッシュしているmemcachedとの通信程度です。memcachedは同一LAN(100Base/TX)内の別のホストに配置しており、ベンチマーク中のmemcachedトラフィックは、〜4Mbits/sec程度。
結果
※縦軸はスループット(Requests/sec)、横軸はApacheBenchの接続並列度。
HTによる底上げ効果は15%
まぁまぁですね。
Core i7で、同時接続数が1つの時だけ、結果が底上げされているように見えるのは、おそらくTurbo Boostが作動した結果かと。
不思議なのは、同時実行可能なスレッド数が同じく4個である、Core i7(HT off)とPhenomで、スループットのピーク位置が異なること。Phenomはピークが5並列で、これは4コアであることを考えれば妥当なのだけれど、Core i7(HT off)のほうは、ピークが7並列の時であり、しかも3並列→4並列→5並列と、完全にリニアに伸びている。誰か解説してくれないかなぁ。。
しかしHT導入で気になるのは、OSのカーネルがタスクスケジューリングする上で、HTの存在をどれほど考慮してくれるのか、という点。HTによって2スレッド同時並列で実行できるといっても、それぞれのスレッドがコア内の限られた演算器を奪い合うことになって、当然互いの実効性能に大きく影響を及ぼすので、スループットはトータルでせいぜい10%〜20%増しくらいかな? つまり個別のスレッドに注目すると、その実効性能は55%〜60%に低下してしまうのではないかと思うわけです。
だとすれば、もしカーネルが論理CPUと物理CPUを同等に扱い、他に空いているコアが存在するにも関わらず、2つの重いプロセスを同一のCPUコアに割り振ってしまった場合、深刻な性能低下が見られるかもしれないわけで。これは一つのCPUにコアがひとつしか載っていなかったPrescott時代では存在せず、メニーコアが実現された今の時代ならではの話だと思うのですが(まぁでも当時のPen4アーキテクチャなXeonでもHT Enableだったし、Xeonを4個載せたサーバもあっただろうから、以前から存在する問題なのでしょうね)。
Linuxについては、カーネルMLでこんな投稿("fully HT-aware scheduler" support, 2.5.31-BK-curr)を見つけたので(2002年の投稿)、今ではカーネルでちゃんと手当されているのかもしれませんね。Winowsではどうなんだろう。