スピード狂ですか?道路でのスピードの出し過ぎは厳禁ですが、パソコンはできるだけ早く動いてほしいですよね。そこでパソコン上でより高速に動くプログラムを書くためにはどうすれば良いかを紹介しましょう。
一般的な書き方の問題もありますが、今回はgccの使い方に関してのお話をしましょう。
GNU Compiler Collectionは多種多様なアーキテクチャーと言語をサポートする便利なコンパイラです。当サークルでは新入生教育のPC上でのプログラミングからマイコンであるAVRやH8向けのプログラミングの際にも利用しています(最近はH8を使う人はほとんど居ませんが)。ただ、このgccは多機能すぎるためにオプションが大量にあって分かりづらいです。そこで今回はgccの主要なオプションを紹介します。
まずは必ずつけるべきオプションから
警告を有効にする。-Wall
これは必ずつけるべきです。警告はできるだけ出ないようなプログラミングを心がけましょう。多くのバグや可読性の問題をしてくれます。
さて、ここから本題の最適化オプションを紹介しましょう。最適化オプションはgccのドキュメント”Optimize Options“に詳しく載っていますが、私がよく利用しているオプションを紹介します。
最適化オプション -O2または-Os
基本の最適化オプションですね。どちらも同じくらいよく用いられます。gccは各最適化を一つずつON/OFFできますが、それは面倒なので一括してON/OFFできます。まずは-O2ですね。これは多くの場合適切な最適化を行います。具体的にどのような最適化を行うかはドキュメントを参照してください。迷ったらこれでいいでしょう。次に-Osです。これは-O2で有効になるオプションのうち通常ファイルサイズが大きくなるオプションを無効化した上で、ファイルサイズを小さくするための最適化を行います。マイコンではメモリの節約なり有効ですし、パソコンでもバイナリサイズが小さくなることでCPUキャッシュにうまく載るようになって-O2より高速になる場合もあるようです。スピード狂の方は両方でコンパイルしてテストしましょう。
最適化オプション-fomit-frame-pointer
これはデバッグビルドをしなければ有効になるはずですが、-gオプションをつけつつ高速なバイナリを生成したいときに使いましょう。ただし、一部のアーキテクチャーではデバッグ不能になるらしいですのでご注意を。
コンパイルオプション -pipe
これはコンパイル結果には影響を及ぼしませんが、コンパイル時間の短縮につながります。ただし、メモリを多く必要とします。今時のPCなら問題ないでしょう。
最適化オプション-mtune=
これはi386またはx86-64系のみのお話です。つまり一般的なパソコンでのお話しになります。gccは通常古いCPUでも動くバイナリを生成しますが、コンパイルしたPCでしか動かさないなんてことはよくあります。そこで-mtune=を指定すると指定したCPUに最適なバイナリを生成してくれます。=のあとに指定する名前はドキュメントを参照してください。nativeとしておけば今使っているCPU向けに最適化してくれます。なお、このオプションを指定しても特定のCPUに最適化されるのみで、古いCPUでも実行可能なはずです。古いCPUなぞ知らんという方は-march=を使ってください。ただ、こちらの指定にはnativeは使えません。
最適化は便利ですが時々間違った最適化をすることもあります。特にマルチスレッドや割り込みを使ったプログラムはgccの最適化において想定していないのでおかしくなるときがあります。おかしくなったときは-O0として最適化を無効としてみましょう。なおった場合には怪しいところにvolatileをつけて変数単位で最適化を無効にして洗い出しましょう。複数のスレッドから扱う変数には注意が必要です。ただ、ここで扱う範囲を超えるのでマルチスレッドの話はよそを参照してください。
さて、ここまでgccのオプションについて説明してきました。もし、次回を書く気になったときにはコンパイラに依存しないコーディングのお話をしたいと思います。by Y.O