gcc-4.0のCVS版で,gcc-4.0の目玉機能の一つである auto-vectorization(自動ベクトル化?)を試してみる.まだgcc-4.0はリリース前のベータ版でバグもたくさんある.でも今のうちからgcc-4.0で最適化が掛かり易いコードが書けるようになっておけば,今後幸せになれる気がする.
auto-vectorization の概要
詳細は http://gcc.gnu.org/projects/tree-ssa/vectorization.html が詳しい.
要点としては,
- -ftree-vectorize を指定する.
- intel のCPUを使っているなら -msse か -msse2 を指定する.
- -ftree-vectorizer-verbose=数字 で詳細な情報が出力される.
- ポインタには __restrict__ を付ける
実際に試してみる
#define RESTRICTED __restrict__ void foo(int * RESTRICTED src, int * RESTRICTED dest, int length) { while (length-->0){ *src += *dest; src++; dest++; } } int main() { int SZ=4*1024*1024; int* RESTRICTED src=new int[SZ]; int* RESTRICTED dest=new int[SZ]; foo(src, dest,SZ); delete[] src; delete[] dest; return 0; }
たとえば上記のようなコードは
$ g++_4_0 -ftree-vectorize -msse2 -ftree-vectorizer-verbose=2 -O3 test.cpp -o test
でコンパイルすると,関数foo()はインライン展開され,ベクトル化されていた.
大雑把にtimeで処理時間を計測
gcc-4.0 ベクトル化あり
$ g++_4_0 -ftree-vectorize -msse2 -ftree-vectorizer-verbose=2 -O3 test.cpp -o $ time ./test user 0m0.010s
gcc-4.0 -O3 だけ
$ g++_4_0 -O3 test.cpp -o test $ time ./test user 0m0.016s
gcc-3.4 -03 だと
$ g++ -O3 test.cpp -o test $ time ./test user 0m0.019s
icc と比較
$ icc -fast ./test.cpp $ time ./test user 0m0.013s
ってな結果になった.ただし,この結果はベクトル化なしでの値.iccでは次のような理由でベクトル化されなかった.
$ icc -vec_report5 -fast test.cpp IPO: performing single-file optimizations IPO: generating object file ipo_icc7y2d3.o test.cpp(24) : (col. 6) remark: vector dependence: assumed FLOW dependence between reference at line 24 and reference at line 24. test.cpp(24) : (col. 6) remark: loop was not vectorized: existence of vector dependence.
結論
むー.面倒だ.