インテル® C++ コンパイラー 18.0 デベロッパー・ガイドおよびリファレンス
関数のインライン展開は、IPO で通常必要とされるプログラム全体の解析の基準を満たす必要がないため、この最適化はプロシージャー間の最適化 (IPO) で主に使用されるものの 1 つです。コンパイラーは、頻繁に実行する関数呼び出しが存在していると判断した場合、その呼び出し命令を、当該関数自体のコードに置き換えます。
関数のインライン展開は、比較的大きな関数よりも小さなユーザー関数でよく行われます。この最適化は、次の操作を行ってアプリケーションのパフォーマンスを向上します。
関数呼び出しの引数の設定の必要性を排除する
関数の呼び出し分岐を取り除く
定数を伝播する
関数のインライン展開を行うと、関数呼び出しのランタイム・オーバーヘッドがなくなるため実行時間は短くなります。しかし、インライン展開を行うと、コードサイズやコードの複雑性が増し、コンパイル時間も長くなります。一般に、コンパイラーに関数のインライン展開を指示すると、より広いコンテキストでソースファイルが検証され、より多くの最適化の機会を見つけることができます。
[Q]ip コンパイラー・オプション (単一ファイル IPO) を指定すると、現在のソースファイル内で定義されているプロシージャーへの呼び出しに対して関数のインライン展開を行います。一方、[Q]ipo コンパイラー・オプション (複数ファイル IPO) を指定するとその他のファイルで定義されたプロシージャーへの呼び出しに対して関数のインライン展開を行います。
[Q]ip と [Q]ipo のどちらのオプションを指定した場合も、条件によってはコンパイル時間とコードサイズが著しく増える場合があります。
インテル® コンパイラーは、デフォルトで[Q]ip オプションを指定した場合と同じようなインライン展開を行いますが、一般にその量はこのオプションを指定した場合よりも少なくなります。
コンパイラーはどのルーチンをインライン展開すればプログラムのパフォーマンスに最も寄与するかを調べて選び出します。この選択は、デフォルトのヒューリスティックを使用して行われます。プロファイルに基づく最適化 (PGO) のオプション ([Q]prof-use) を使用するかどうかによって、コンパイラーが使用するインライン展開ヒューリスティックは異なります。
[Q]ip または [Q]ipo で PGO を使用する場合、コンパイラーは次のガイドラインに沿ってヒューリスティックを適用します。
デフォルト・ヒューリスティックでは、プログラムに対して収集されたプロファイル情報を基に、最も頻繁に実行される呼び出しに重点がおかれます。
デフォルト・ヒューリスティックを使用すると、インライン展開の最低条件を満たしている非常に小さな関数は必ずインライン展開されます。
IPO の PGO との併用
IPO と PGO を組み合わせると、通常 IPO を単独で行うよりも良い結果を得られます。PGO は、IPO で用いられる静的プロファイル情報よりも良質な最適化の機会を提供する動的プロファイル情報を生成します。
コンパイラーは、ソースコードの特性を使用して、最も頻繁に実行される関数呼び出しを推定します。この推定は上記の PGO ベースのガイドラインに適用されます。ソースの静的特性に基づいた、頻度の推定は、必ずしも正確であるとは限りません。
デフォルトでは、標準ライブラリー関数と数学ライブラリー関数のいくつかは、関数の呼び出し時点で、コンパイラーによって自動的にインライン展開されます。通常、この処理によって計算速度が速くなります。
libirc、libm、または svml ライブラリーの多くのルーチンは、互換マイクロプロセッサーよりもインテル製マイクロプロセッサーでより高度に最適化されます。
-fno-builtin オプション (Linux* および macOS*) または /Qno-builtin-<name> と /Oi- オプション (Windows*) は、組込み関数のインライン展開および名前による認識サポートとその最適化を無効にします。/Qno-builtin-<name> オプションは、ほぼすべての組込み関数を無効にする /Oi- オプションよりも細かい関数レベルでインライン展開を無効にできます。これらのオプションは、標準ライブラリー・ルーチンを独自のバージョンで再定義し、そのルーチンのバージョンが標準ライブラリー・ルーチンと同じ名前の場合に使用します。
関数のプリエンプションを使用するには、fpic オプションを指定しなければなりません。デフォルトでは、コンパイラーはプリエンプションに必要な位置に依存しないコードの生成を行いません。