GCC 4.4 情報

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

OpenMP 3.0 対応

OpenMP 3.0 に対応しました。

その他最適化関連

その他の最適化処理でも改良が加えられており、対応するコマンドラインオプションも増えています。

  • -findirect-inlining
  • -ftree-switch-conversion
  • -ftree-builtin-call-dce
  • -fconserve-stack

最後の -fconserve-stack は、処理速度よりもスタックの消費量を少なくすることを優先してコードを最適化するもので、組み込み系やカーネルなどメモリが潤沢に使えない環境では重宝するオプションになるかもしれません。

AES PCLMUL AVX への対応

intel の AES PCLMUL AVX に対応しました。
それぞれ -maes -mpclmul -mavx というコマンドラインオプションで有効になります。

C++0x サポート

次期ISO標準として仕様策定中の C++0x への対応も進んでいます。

コンパイラオプションで -std=c++0x か -std=gnu++0x を指定すると使えます。

詳細は、http://gcc.gnu.org/gcc-4.4/cxx0x_status.html

その他変更点

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 を参照してください。

ベンチマーク

最後に、手元のコードを gcc-4.3 と gcc-4.4 のそれぞれでビルドしてみて、生成されたバイナリの処理速度を比較してみました。コンパイルオプションは -O3 のみ、PCは linux + pentium4 です。

gcc-4.3 gcc-4.4
97 秒 87秒

というわけで、1割程速くなりました。手元のコードで試した限り特に問題は生じませんでした。 fedora の次期リリースは GCC は4.4系を採用するという話も聞きますし(そもそもgccの開発にはかなりredhat/fedoraが関わっています)、4.4系は順調な仕上がりのようです。