Eyes, JAPAN Blog > gccのコンパイルオプションについて

gccのコンパイルオプションについて

ishikuro

この記事は1年以上前に書かれたもので、内容が古い可能性がありますのでご注意ください。

石黒です。

今日はgccのコンパイルオプションを考えたいと思います。ベンチマークを取ったり厳密に調査をしたわけではないので、紹介だけです。

UNIX系OSのカーネルをはじめとして、GNUのツールの大半や多くのオープンソースソフトウェアはCで書かれています。そして自分の環境にあったバイナリ形式で配布されていない場合、ソースコードのアーカイブを取得して、コンパイルする必要があります。このとき、Linuxではgccがよく使われます。会津大学では1年生からgccでプログラミング演習を行っていますね。なにもPC-UNIX界にgccしかないわけではなく、より高速なバイナリを生成するintel製Cコンパイラを使う人もいるようですし、FreeBSDではLLVM ClangというCコンパイラに移行する動きもあるそうです。しかしここではgccを使うことにしてすすめたいと思います。

さてgccでは最適化オプションを設定すると、通常より高速なバイナリを生成することができます。中間コードでアセンブラを吐くのですが、そこからアルゴリズムに手を加えるようにするのです。詳しくどのような仕組みになっているかはInterfaceさんのコラムをご覧ください。様々な種類のオプションを指定することができます。

そんな便利なものがあるならば最初から有効になっていないのか?という疑問が沸くと思います。実は大抵の配布パッケージに同梱されているコンパイル用スクリプトではある程度有効になっています。しかし最適化オプションは両刃の剣で、デバッグを不可能にしてしまったり、特定環境に特化したものや、プログラムによっては誤作動を起こすものがあります。なので込み入った部分は自分で試行錯誤をして定める必要があります。

それでは具体的に設定する方法を紹介します。コンパイル用スクリプトやgccでは環境変数CFLAGSを読みますからあらかじめそこに最適化オプションを代入しておくことになります。Gentooユーザであれば/etc/make.confに記述することで簡単に設定できますね。

私は以下のようにしています。(環境変数はシェルの種類に合わせて適宜設定することになります)

CFLAGS=”-march=native -funroll-loops -fforce-addr -O2 -pipe -msse -msse2 -msse3 -m3dnow -mmmx -mfpmath=sse ”

意外とあっさりです。たくさん設定していた時期もありましたがfirefoxなどがよく落ちるようになったので慎重に削っていきました。私は中間コードのアセンブラなどの知識が無いので厳密な意味はわからないことがほとんどです。

  • -march=native: 自動的にそのアーキテクチャにそったオプションをつけてくれます。調べたところ、これは実際自分のマシンでは-march=k8-sse3 -mcx16 -msahf –param l1-cache-size=64 –param l1-cache-line-size=64 -mtune=k8 に置き換わっているようです。
  • -funroll-loops: ループの展開を行います。バイナリサイズは増えるのかもしれません。
  • -fforce-addr: ある計算をメモリ上ではなくCPUのレジスタにコピーして行うようにします。
  • -O2: この他に-O0(最適化無し), -O1, -O3がありこの数字の順に強い最適化をかけます。実際は最適化オプションの集合です。-O3までかけない理由はうまく動かなくなる場合が経験上多かったからです。
  • -pipe: 中間ファイルをディスクに書き込まずにメモリ上で処理します。これは生成されるコードには影響しませんがコンパイルの待ち時間が少なくなります。
  • -msse -msse2 -msse3 -m3dnow -mmmx -mfpmath=sse: CPUの拡張命令セットを使うようにします。

厳密に意味が分かればいいのですが大体はWeb上の受け売りから、不審な動作をするものを削るというかたちで調整していきました。しかし指定するのとしないのではかなりの違いがあります。私は標準的なコマンドなどが入っているcoreutilsというパッケージから全て最適化して組んでいますが、WindowsのオフィシャルビルドのFirefox3.x系よりも同じマシンの最適化されたLinuxの2.x系のほうが起動、終了、レンダリングの体感速度は上でした。

GCCのバージョンは意外と速いペースで上がっていくのでWebで見つけたオプションが自分の使っているバージョンでも有効である保証はなく、注意が必要です。また、カーネルやGCCそのものといったクリティカルなパッケージについてはやらないほうがいいです。でも、もし時間が許すならいろんなパッケージで試してください。コンパイルが快感になりますよ。

担当:石黒

  • このエントリーをはてなブックマークに追加

Comments are closed.