spu-gccによる最適化

以前やったN-Queen問題では,コードのコンパクトさを期待してCで全て書いていた.
しかし,現在は全てC++で書くようにしている.
なぜかというと,単純に表記が自由だということもあるが,128-bit代入で警告を出さないことと,参照を用いた関数をインライン化すると,きちんとレジスタにしてくれるということが分かったからだ.
今書いているコードでは,8方向への効きを8つの変数に代入するのだが,最初の非効率的な実装は


void get_mobilities( vector unsigned int assembly, vector unsigned int* mobilities );
という定義だった.

これはメモリアクセスが発生するので大変効率が悪い.そこで


vector unsigned int get_mobitlity_0( vector unsigned int assembly );

という関数を8つ書いたのだが,この場合,共有できる計算を無駄に繰り返していること,そしてより重要なことに,効きを取得する場所全てで8行分コードを書かなければならないということが問題だった.
効率は重要だが,コードを読みにくくなるとデバグもしにくい.

そこで恐る恐る


vector unsigned int get_mobilities( vector unsigned assembly, vector unsigned int&m0, ... );

という形で参照を使った関数として-finline-functionsオプションでコンパイルしたところ,ちゃんとレジスタのまま計算してくれていた.
インライン化をせずに実行すると,この関数は3倍近い時間を消費した.

関数の呼び出しもSPUでは非常にコストがかかるので,できるだけ減らすべきだし,インライン化の効果が高い.
また変数定義をできるだけ遅らせることができるので,うまく最適化をしてくれれば呼び出し前に退避するレジスタの数も減らせる.
こういったことから,効率面からもC++を使用した方がよいし,どうせCellBE以外の使い回しのできないコードなのだからCで書く必要はないというのが現在の結論だ.
ただし,バイナリサイズが膨らむようなことがあったら考えなければならないだろう.