GCCの次期バージョン 4.4 系ですが、ついに rc1 がリリースされました。そこで実際にGCC 4.4.0-rc1 を試し、変更点・残っているバグなどを調べてみました。
なお、オフィシャルなドキュメントは以下のURLにまとめられています。
特に後者は一度は目を通すべき内容で、gccの仕様変更に伴いコンパイルエラーになってしまうコードの例と対処方法がまとめられています。
以下、変更点、ベンチマーク結果などをまとめます。
最適化関連
4.4系では、最適化機能がさらに改良されています。
Graphite
まず graphite ブランチで開発されてきた、新しい最適化の枠組みが取り込まれました。
http://gcc.gnu.org/wiki/Graphite
これはfor文やwhile文で記述した繰り返し処理を最適化するもので、参照するデータ間の依存関係を解析することで、たとえばキャッシュのヒット率が向上するようにループ処理を自動変換します。
具体例をあげると、たとえば
int A[N][M]; for (int m=0;m<M; ++m) for (int n=0;n<N; ++n) A[n][m] = A[n][m] * 2;
というコードは、コンパイル時にgcc内部で次のように自動変換されます。
int A[N][M]; for (int n=0;n<N; ++n) for (int m=0;m<M; ++m) A[n][m] = A[n][m] * 2;
実行時の配列Aに対するメモリアクセスを考えると、変換後のコードの方がメモリアクセスは連続的になります。つまり変換後のコードの方が実行時のメモリキャッシュのヒット率が高くなるため、より高速に動作します。特に、CPUのキャッシュサイズよりも N*sizeof(int)のほうが大きい場合に、この最適化は有効です。
関数単位での最適化オプションの設定
関数単位で最適化オプションを指定できるようになりました。
http://gcc.gnu.org/onlinedocs/gcc/Function-Specific-Option-Pragmas.html
AES PCLMUL AVX への対応
intel の AES PCLMUL AVX に対応しました。
それぞれ -maes -mpclmul -mavx というコマンドラインオプションで有効になります。
その他変更点
- プリプロセッサの解釈が厳密になった。
gcc-4.3以前では
#if 1 #elif #endif
という厳密には誤りのあるコードもコンパイル出来ていました。一方gcc-4.4は
error: #elif with no expression
と、厳密に構文エラーと解釈してくれます。対処方法は簡単で
#if 1 #else #endif
と書き換えればOKです。
- "warning: dereferencing type-punned pointer will break strict-aliasing rules" という警告がでる。
"-O3"などを指定していると、上記のエラーが出る場合があります。とりあえず "-fno-strict-aliasing"をつければ回避できます。正しい対処方法は *1 を参照してください。