●
-ffinite-math-only
結果が「非数値」あるいは「無限」ではないと仮定して浮動小数点演算のための最適化を行うオプションです.
この場合の「非数値」はNAN(not a numberの意味)です.0.0/0.0の値をNANと名付けます.
ソースと生成されたコードをリスト1〜リスト3に示します.
最適化の結果,関数内の変数x,yともに直接NAN値がセットされています.むだな計算は排除されています.
ちなみに,NANはC99規格で規定されています.GCC2.95では使用できませんでしたが,現バージョンでは使用できます.ソースを見てわかるように,_GNU_SOURCEを定義することによってGNUライブラリの拡張関数の宣言が有効になります.
● -fforce-addr
このオプションを付加すると,メモリ中のアドレス定数を,算術演算で使用する前にレジスタにコピーします.このオプションにより,処理速度が多少速くなる場合があります.
ソースと生成されたコードをリスト4〜リスト6に示します.
オプション付きで生成されたソースを見ると,printfを呼び出す前にレジスタaxに値をセットしてから処理しています.一方,オプションなしで生成されたソースでは,レジスタが指しているアドレスの内容を使用しています.
メモリ中の数値を演算するよりもレジスタに格納された数値を演算するほうが,もちろん速くなります.このオプションは試してみる価値があると思います.
なお,-fforce-memオプションは,メモリ・オペランドについて算術演算を行う前に,そのメモリ・オペランドをレジスタに強制的にコピーして,すべてのメモリ参照を潜在的な共通部分式とします.しかし,この処理は可搬性の面では有害で,最適化とはいえないように思えます(リスト7).
● -fomit-frame-pointer
このオプションを付加すると,フレーム・ポインタを必要としない関数の場合,フレーム・ポインタをレジスタにもちません.これにより,フレーム・ポインタをセーブ,設定,リストアする命令をなくすことができます.結果として多くの関数で利用可能なレジスタが一つ増えます.問題はGDBによるデバッグが不可能になってしまう点です.
GDBによるデバッグ作業中は,ユーザ・プログラムが関数呼び出しを行うたびに,その呼び出しに関する情報が生成されます.その情報には,ユーザ・プログラム内においてその呼び出しが発生した場所,関数呼び出しの引き数,呼び出された関数内部のローカル変数などが含まれます.その情報がスタック・フレームと呼ばれるデータ・ブロックに保存されます.そのデータを参照するためにフレーム・ポインタが必要となります.
ソースと生成されたコードをリスト8〜リスト10に示します.
このように関数の出口と入口で行っている処理が省略されています.もちろん,GDBを使う際には,このオプションを付けないほうがわかりやすいと思います.
● -fschedule-insns
ターゲット・マシン上でこのフラグがサポートされている場合,必要なデータを利用可能になるまで待つことによる実行の遅延を防ぐために,命令の順番の変更を行います.これは遅い浮動小数点命令やメモリ読み込み命令の実行において,それらの結果を必要とする命令の前にほかの命令を詰め込みます.
ただし,この処理を行うと,デバッグ時に混乱すると思います.しかし,完成版をコンパイルするときに使用すれば,速度の高速化が図れるはずです.
● -fschedule-insns2
前のオプションと似ています.実行の遅延を防ぐためにレジスタに数値を割り当てるといった最適化を行います.やはりデバッグが難しくなるでしょう.
 記事内インデックス 連載インデックスはこちら Interfaceのトップ |
|
|
Copyright 2004 岸 哲夫
Copyright 1997-2004 CQ Publishing Co.,Ltd.