マツド・サイエンス研究所

クワッドコアの威力

前々回のコンテンツ「宇宙船で小惑星帯を通り抜けるとき、どのくらい小惑星に接近するの?」の計算では、Phenom X4 を使ったのだが、せっかくクワッドコアを持っているのに一つのCPUコアしか使わずに計算した。そのため、計算に約28時間(正確には1665.8分間)もかかった。

そこで、プログラムを修正して、クワッドコア対応で計算してみた。

プログラムはasteroidInterval3X.rbだ。前々回のプログラムと使い方はほとんど同じなのだが、引数が一つ増えている。

$ ./asteroidInterval3X.rb 0 4 >asteroidInterval3X.dat

とやると、4つのタスクを起動し、それぞれに53万個の小惑星を4分割して、13万2500個ずつ割り当てて計算させる。

それぞれ、別のコアが並列で計算した後、最後に4つの結果をシミュレーション時間毎に最短距離を選ぶようにマージする。6コアのCPUならば、最後の引数を6にすれば、全てのコアをフルに使える。さらに、ハイパースレッド対応のCPUの場合、例えば、6コアかつハイパースレッドならば、12を引数にすれば、全てのスレッドを使うことができる。

私の場合、ハイパースレッド非対応のクワッドコアなので、引数を4にして計算した結果が、冒頭のグラフだ。赤線でシングルコアで計算した結果を、緑線でクワッドコアで計算した結果を示しているが、ほとんど赤と緑が重なっているので、計算結果はあっていることがわかる。

プログラム以外は同一の条件だ。

・Phenom X4 9350e 2GHz

・8GBメモリ

・Ubuntu 10.04 32ビットPAEカーネル

・Ruby 1.8.7

で、計算時間は、

・シングルコア:約28時間(正確には1665.8分間)

・クワッドコア(引数:4):約3時間半(正確には207.3分間)

となり、ちょうど8分の1の時間で済んでる。

8分の1・・? クワッドコアなんだから、4分の1 じゃないか? (ちょっと、わざとらしい)

実は、私が作ったアルゴリズムでは、前回説明したように、小惑星の個数の1.5乗と計算時間が比例する。つまり、小惑星の個数を少なくすると計算時間が、それ以上に減る。だから、8分の1であっているのである。

じゃあ、さらに分割すれば、もっと短い時間で計算できるはずである。

実際、引数を4から16にすると、さらに半分の103.3分で計算が済む。この場合、各コアが4つずつのタスクが割り当てられているのだが、それでも計算時間が少なくなるのだ。

さらに引数を2倍の32にすると、2の平方根分短くなるはずで、実際77.0分で終わった。

調子に乗って、引数を64にすると、50分くらいで終わるはずだ・・・と、やってみたら、オペレーションシステム自体がアボートしてしまった。

まあ、全てを別タスクにすること自体が間違っていたので、本当のところは、タスクはコアもしくは、スレッドの数だけにして、その中で、小惑星の個数を分割して計算した方が良いに決まって居る。けど、まだプログラムを改修してない。

既に、まきのさんがコメントしているように、究極的には、全ての小惑星を個々に、つまり一個ずつ計算して、後からマージするのが、最も良いことになる。

ただし、これは、現状では、「小惑星の個数の1.5乗と比例する計算時間」が支配的だが、あまり細かく分割すると「ミュレーション時間毎に最短距離を選ぶようにマージする時間」の方が大きくなってしまう可能性もあるだろう。

本当のところ、何処に最適解があるかは、もう少し作業してみないと判らない。

けど、速度が欲しいなら、RubyじゃなくてCでコンパイルしろ・・とも言われる。

注意

ブログのコンテンツの内、「告知」など時期よって情報価値が無くなるのは除いてある。また、コンテンツに付いたコメントは書き込み者に著作権があるものと判断し、ここに持ってきていないので、コメントを見るときは、元々のブログコンテンツを参照してもらいたい。

その他、ブログ発表後、コメントなどの内容を反映するなど、内容を変更しているものもあるので、注意してほしい。