Hatena::ブログ(Diary)

yukobaのブログ このページをアンテナに追加 RSSフィード Twitter

2009年02月10日 Amazon EC2を高速化する方法

Amazon EC2高速化する方法

Amazon EC2 に High-CPU Extra Large Instance (c1.xlarge) というのがありまして、8コアのCPUと7GBのメモリを持っています。CPUは Intel Quad Core Xeon が2つ載っているものが多いそうです。

しかし、こいつがくせ者で、no title でも、取り上げられていますが、いまいち速くならない!

top コマンドで、1を押すと、各コアのCPUの使用状況が見れるのですが、2〜4コアしか使ってくれません。しかも、使用コア数は、動的に変化します。いろいろ試して発見したのですが、nice -n -20 を使って、プロセスプライオリティをあげると、6〜8コア(だいたい8コア)を使ってくれて、期待通りの計算速度で動いてくれます。なぜ?なぜ?なぜ?バーチャルコアの割り振りはどういう仕組みになっているのでしょうか?8コア使ってくれないときの、未使用コアのCPU使用率は0%になっています。

Amazon EC2 の High-CPU Extra Large Instance は期待通りの速度で動くと、並列化が100%うまくいくタスクならば、Intel Core i7 の2倍くらいの速度で計算してくれます。

追記1

no title にこの件に関して、c1.xlarge は4GFLOPS出るのではないかと、コメントしてみました。

追記2

起動時の画面は、4657.44 BogoMIPSで、L1 I 32K、L2 D 32K、L2 4096K になってます。これによると、4.5 GFLOPS ですね。(って、BogoMIPSをFLOPSにしちゃだめか)

追記3

(追記6で再度訂正)

Quad Core 2つと書きましたが、Dual Core 4つの気がします。根拠は、

  1. 2次キャッシュが4MBと小さいこと。Quad Coreなら、もっと大きいです。
  2. High-CPU Medium Instance が Dual Core の2.5GHz〜3.0GHz となっていること。

かなり、想像ですが、Dual Core の 2.5GHz〜3.0GHz を、High-CPU Extra Large Instance は CPU が暇なときは1つだけ、忙しくなると(CPUリソースが不足すると)最高4つ割り当てるように、動的に切り替えている気がします。「不足すると」の判断基準がわからないです。

そして、その、空いたCPUの隙間を、High-CPU Medium Instance で埋めていっている気がします。もし、これが正しいならば、本当に動的だなぁ。

追記4

ページが見つかりませんでした | 理化学研究所情報基盤センター(所内および所外向け) をがんばってコンパイルしてみました。Fortran90 + MPI を使ったのですが、mpirun で -mpinice -20 を指定すると、2コアくらいから、5〜6コアくらいまで増えてくれるんですが、どうしても8コア全て使ってくれない!自作プログラムだと、結構8コア使ってくれたんですが…

追記5

追記だらけ。追記1の件ですが、syoyoさんによると、シングルスレッドベンチマーク結果だそうです。no title

追記6

うわ、追記3、適当なこと書いてる。cat /proc/cpuinfo でみれるんですが、Intel Quad Core Xeon E5345 2.33GHz が多いです。L2 は 4MB×2 = 8MB だそうです。

しげっちしげっち 2009/02/11 11:13 サービスメニューによると、Amazon EC2はdedicated CPUを割り当てているらしいので、開いたときだけ他のインスタンスが割り込むような処理はしてないんじゃないかと信じてます。(信じてるだけですが…)
仮想化された環境では、スレッドスイッチが多発するプログラムはなかなかスケールしないかもしれません。いろいろとSMPのOSスケジューラとVMの間には複雑な関係があって、一度IDLEになったCPUが怠けやすい気がします。スレッドが細かい単位でスケジューラに戻されると同じCPU上でぐるぐるスレッドスイッチされやすくなるような気がします。
うまく言えませんが、nice値を上げるとスレッドがCPUに張り付きやすくなって、他のスレッドをOSがプロセスを上手くディスパッチしてくれるようになるんだと思います。

yukobayukoba 2009/02/11 18:58 > しげっちさん

なるほど、同じコアに異なるスレッドを振ってしまった後に、どうやって、コアからスレッドを引きはがすかという部分は、VMとOSの相互作用に強く依存してそうですね。

syoyosyoyo 2009/02/11 21:04 こんにちは

興味深い指摘ありがとうございます.
確かに nice をつけないとコアを使ってくれませんね.
自作レンダラで以下のような画像をマルチスレッドでレンダリングさせてみて、medium と xlarge でパフォーマンスを取ってみました.
http://www.flickr.com/photos/32862412@N07/3102877052/

medium:
(スレッド数 : 処理時間(nice をつけたときの処理時間))
1 : 54 sec(54 sec)
4 : 27 sec(22 sec)

xlarge:
1 : 41 sec(41 sec)
4 : 41 sec(21 sec)
8 : 21 sec(15 sec)

単体スレッドでの性能では xlarge のほうが良いですね.
nice をつけてもスケールしないのはレンダラアプリ自体がコア数に比例して十分スケールできていないから、というのも原因のひとつとしてあります.

うーん、でも xlarge で nice をつけないと 1 スレッドでも 4 スレッドでも結果が同じというのは損している気分です :-)

マルチスレッドでやるよりは、マルチプロセスでアプリを走らせたほうが EC2 に向いているかも...

yukobayukoba 2009/02/11 22:43 > syoyoさん

おお!ベンチマーク大変ありがとうございます。nice 効果は僕だけかと不安だったのですが、syoyo さんも同じ結果が出るということは、Amazon EC2 全体の問題のようですね。

> マルチスレッドでやるよりは、マルチプロセスでアプリを走らせたほうが EC2 に向いているかも...

マルチプロセスでも同じですよ。眠ったコアはなかなか起きてくれません。

syoyosyoyo 2009/02/12 01:10 yukoba さん、
仮想環境はよくしらないのですが、以外と難しい話かもしれません.

というのは、今回のレンダラアプリではそう多くはありませんが、スレッド間の同期(pthread mutex)を使います. そして、物理的に分離している CPU 間(たとえばなんらかの Dual core CPU と Dual core CPU 間)で同期処理が生じると、これはきっとベラボーな時間がかかることになるはずです. 実際、現在のリアルな Intel 8 core でも、中身は Quad x 2 になっているわけですが、Quad 間の同期は FSB をまたぐことになりとてもパフォーマンスが落ちます(かなり並列化が聞くようなアプリでも、結局このボトルネックのせいで 8 core で x6 倍くらいしかでないということになったりします).

EC2 の仮想環境を動かしているカーネルはそこらへんを考えて、スレッドの割り当てをなるべく物理的なコア間だけに割り当てているのかもしれません. まあ妄想ですが...

> マルチプロセスでも同じですよ。眠ったコアはなかなか起きてくれません。

これについては、たとえば今回のレンダラアプリですと絵を計算するわけですが、1 枚をマルチスレッドで計算するか、8 枚をシングルスレッド(8 プロセス)で計算するかという並列モデルの違い、ということを言いたかったのです.

前者は一枚の絵を可能な限り高速にレンダリングするわけですが、同期や今回の EC2 の問題(?)などによりコアをフルに使えないとパフォーマンスが出なくてもったいないことになります.

後者ですと、一枚の絵を計算する時間は同じでも、8 枚同時に処理しているので、8 枚をレンダリングし終わったあとは実質前者において 1 枚を 8 倍でレンダリングしているのと同等ということになります. こちらの問題はメモリや IO が 8 倍必要になるということになりますが、利点としてはスレッド同期などの問題がないのと、プロセスがコア数分を確実に使ってくれるということになります.
実際 EC2 で今回のレンダラアプリを 8 プロセス起動したら, nice を使わずとも 8 core きちんと使ってくれました(それぞれの実行時間は 1 core のときとほとんど同じ).

EC2 は web サーバ系での利用を考えていると思うので、その意味でもマルチプロセスでやるのが適しているのかなと思った次第です.

トラックバック - http://d.hatena.ne.jp/yukoba/20090210/AmazonEC2