@ledsun blog

Hのキーがhellで、Sのキーがslaveだ、と彼は思った。そしてYのキーがyouだ。

nbodyのチューニング

benchmarksgame-team.pages.debian.net

スクリプトをチューニングします。 特に知見はないので、思いついた色々なパターンを試して、雰囲気を掴んでみましょう。 ソースコードはURLのみ載せます。

変更前

https://github.com/ledsun/nbody/blob/main/hoge.rb

64秒

move_from_i関数を攻める

move_from_i関数が何回も呼ばれるのでそこを重点的に攻めます。

引数をいじる

dt

方法 時間 ソースコード
定数にする 49秒 https://github.com/ledsun/nbody/blob/main/const_dt.rb
直値にする 51秒 https://github.com/ledsun/nbody/blob/main/inline_dt.rb
グローバル変数にする 54秒 https://github.com/ledsun/nbody/blob/main/global_dt.rb
クラス数にする 69秒 https://github.com/ledsun/nbody/blob/main/class_variable_dt.rb

定数にするとJITが効きやすくなるのでしょうか?一番速かったです。 直値でも定数と同じぐらい速そうなのに、そうでもありません。 グローバル変数にするのも効果があるようです。 クラス変数は参照するのにメソッド経由したので、遅くなりました。

nbodies

方法 時間 ソースコード
グローバル変数にする 57秒 https://github.com/ledsun/nbody/blob/main/global_nbodies.rb

dtほどではないですが効果があるようです。

dtとnbodiesを両方いじる

方法 時間 ソースコード
定数にする 49秒 https://github.com/ledsun/nbody/blob/main/const_dt_and_nbodies.rb

dtだけを定数にするのと変わりません。

dtとnbodiesとbodiesを全部いじる

方法 時間 ソースコード
定数にする 50秒 https://github.com/ledsun/nbody/blob/main/const_dt_and_nbodies_and_bodies.rb

遅くなりました・・・。

ループを展開する

方法 時間 ソースコード
定数にする 55秒 https://github.com/ledsun/nbody/blob/main/inline_inner_loop.rb

それなりに効果がありそうです。

定数化とループ展開を両方やる

方法 時間 ソースコード
定数にする 52秒 https://github.com/ledsun/nbody/blob/main/const_dt_and_nbodies_and_inline_innerloop.rb

組み合わせるとイマイチです。

add_v関数を展開する

方法 時間 ソースコード
定数にする 76秒 https://github.com/ledsun/nbody/blob/main/inline_add_v.rb

遅っ!

move_from_i関数の呼び出し側を攻める

ループを展開する

方法 時間 ソースコード
定数にする 55秒 https://github.com/ledsun/nbody/blob/main/inline_outer_loop.rb

それなりに効果がありそうです。

定数化も同時にやる

方法 時間 ソースコード
定数にする 49秒 https://github.com/ledsun/nbody/blob/main/const_dt_and_nbodies_and_inline_outerloop.rb

定数化と同時にやる意味はなさそうです。

move_from_i関数の中と外を同時に

方法 時間 ソースコード
定数にする 61秒 https://github.com/ledsun/nbody/blob/main/inline_double_loop.rb

ループを一つずつ展開するより遅くなりました、がーん。

感想

結局、引数dtを定数にするのが一番速くて、ほかの方法はさして効果が無いようです。 チューニング、何もわかりません。