web-dev-qa-db-ja.com

関数/メソッドにキーワード 'inline'を書くのはいつですか?

C++で関数/メソッドにキーワードinlineを書くのはいつですか?

いくつかの答えを見た後、いくつかの関連質問:

  • C++で関数/メソッドのキーワード 'inline'を書くとき、Inotにしないでください。

  • コンパイラは、いつ関数/メソッドを 'インライン'にするべきかわからないのですか?

  • 関数/メソッドに 'インライン'と書いたときに、アプリケーションがマルチスレッドであるかどうかは重要ですか?

492
Partial

おお、私のペットの覗き見の1人。

inlineは、コンパイラに関数をインライン化するよう指示するディレクティブよりも、staticまたはexternに似ています。 externstaticinlineはリンケージ指令で、コンパイラではなく、ほとんどリンカによってのみ使用されます。

inlineは、関数をインライン展開すべきだと思うことをコンパイラに暗示すると言われています。それは1998年には本当だったかもしれませんが、10年後にコンパイラはそのようなヒントを必要としません。コードの最適化に関しては、人間は通常間違っていることは言うまでもありません。そのため、ほとんどのコンパイラは「ヒント」を無視します。

  • static - 変数/関数名は他の翻訳単位では使用できません。リンカは、誤って他の翻訳単位から静的に定義された変数/関数を使用しないようにする必要があります。

  • extern - この翻訳単位でこの変数/関数名を使用しますが、定義されていない場合は文句を言わないでください。リンカはそれを整理し、何らかの外部シンボルを使用しようとしたすべてのコードがそのアドレスを持っていることを確認します。

  • inline - この関数は複数の翻訳単位で定義されますので、心配しないでください。リンカは、すべての翻訳単位が変数/関数の単一のインスタンスを使用するようにする必要があります。

注意:テンプレートinlineを宣言することは意味がありません、なぜならそれらは既にinlineのリンケージセマンティクスを持っているからです。ただし、テンプレートの明示的な特殊化およびインスタンス化 inlineが必要 を使用する必要があります。


あなたの質問に対する具体的な答え:

  • C++で関数/メソッドにキーワード 'inline'を書くのはいつですか?

    関数をヘッダーに定義したいときだけ。もっと正確に言えば、関数の定義が複数の翻訳単位に現れることができるときだけです。コードを最適化しながら、コンパイラに多くの情報を提供するので、ヘッダーファイルに小さな関数(1つのライナーのように)を定義することをお勧めします。コンパイル時間も長くなります。

  • C++で関数/メソッドにキーワード 'inline'を書くべきではないのはいつですか。

    コンパイラがインライン展開した方がコードが高速に実行されると考えるからといって、インラインを追加しないでください。

  • コンパイラは、いつ関数/メソッドを 'インライン'にするべきかわからないのですか?

    一般的に、コンパイラはこれをあなたよりも上手くできるでしょう。ただし、関数定義がない場合、コンパイラーにはコードをインライン化するオプションがありません。最大限に最適化されたコードでは、通常、すべてのprivateメソッドは、要求してもしなくてもインライン化されます。

    GCCでのインライン展開を防ぐために、__attribute__(( noinline ))を使用し、Visual Studioでは__declspec(noinline)を使用してください。

  • 関数/メソッドに 'インライン'を書いたときにアプリケーションがマルチスレッド化されていても問題ありませんか?

    マルチスレッドは、インライン展開にはまったく影響しません。

776
deft_code

テンプレートの特殊化を行うときは、関数を明示的にインライン化する必要があります(特殊化が.hファイル内にある場合)。

27
BostonLogan

1)今日では、ほとんどありません。関数をインライン化するのが得策であれば、コンパイラはあなたの助けを借りずにそれを行います。

2)いつも。 #1を見てください。

(質問を2つの質問に分けたことを反映するように編集されています...)

18
Aric TenEyck

C++で関数/メソッドにキーワード 'inline'を書くべきではないのはいつですか。

関数が.cppファイルで定義されている場合、あなたはnotキーワードを書くべきです。

コンパイラは、いつ関数/メソッドを 'インライン'にするべきかわからないのですか?

そのような状況はありません。コンパイラは関数をインラインにすることはできません。できることは、関数への呼び出しの一部または全部をインライン化することだけです。関数のコードを取得していない場合は実行できません(その場合、可能であればリンカが実行する必要があります)。

関数/メソッドに 'インライン'を書いたときにアプリケーションがマルチスレッド化されていても問題ありませんか?

いいえ、それはまったく関係ありません。

  • コンパイラは、いつ関数/メソッドを 'インライン'にするべきかわからないのですか?

これは使用しているコンパイラによって異なります。最適化のヒントではなくリンケージディレクティブであるため、今日のコンパイラがインライン化する方法を人間よりもよく知っていることを盲目的に信頼しないでください。私はイデオロギー的にこれらの議論は正しいということに同意しますが、現実に遭遇することは異なることかもしれません。

複数のスレッドを読んだ後、私が作業しているコードに対するインラインの影響を好奇心から試してみました。その結果、GCCではかなりのスピードアップが得られましたが、Intelコンパイラではスピードアップできませんでした。

(詳細:クラス外で定義されたいくつかの重要な関数による数学的シミュレーション、GCC 4.6.3(g ++ -O3)、ICC 13.1.0(icpc -O3);重要な点にインラインを追加するとGCCコードで+ 6%高速化されました。

そのため、GCC 4.6を最新のコンパイラとして認定したとしても、CPUを集中的に使用するタスクを記述し、ボトルネックがどこにあるのかを知っていれば、インラインディレクティブは依然として重要です。

5
meda beda

実際には、ほとんどありません。あなたがしていることは、コンパイラが与えられた関数をインラインにすることを提案することです(例えば、この関数へのすべての呼び出しをその本体で置き換える)。もちろん保証はありません。コンパイラはディレクティブを無視することができます。

コンパイラは通常このようなことを検出して最適化するのに良い仕事をします。

3
DarkSquid

最適化を有効にせずにコンパイルすると、デフォルトでgccは関数をインライン化しません。私はビジュアルスタジオについて知らない - deft_code

Visual Studio 9(15.00.30729.01)で/ FAcsを使用してコンパイルし、アセンブリコードを確認して、これをチェックしました。コンパイラは、debugモードで最適化を有効にせずにメンバ関数の呼び出しを生成しました。関数が__ forceinlineとマークされていても、インラインランタイムコードは生成されません。

2
Jedzia

C++インライン関数は、クラスで一般的に使用されている強力な概念です。関数がインラインの場合、コンパイラはその関数のコードのコピーをコンパイル時に関数が呼び出される各ポイントに配置します。

インライン関数を変更した場合は、コンパイラがすべてのコードをもう一度置き換える必要があるため、関数のすべてのクライアントを再コンパイルする必要があります。それ以外の場合は古い機能を使用します。

関数をインライン展開するには、関数名の前にキーワードinlineを配置し、関数を呼び出す前に関数を定義します。定義済み関数が1行以上の場合、コンパイラーはインライン修飾子を無視できます。

クラス定義内の関数定義は、インライン指定子を使用しなくてもインライン関数定義です。

以下は、インライン関数を使って最大2つの数値を返す例です。

#include <iostream>

using namespace std;

inline int Max(int x, int y) { return (x > y)? x : y; }

// Main function for the program
int main() {
   cout << "Max (100,1010): " << Max(100,1010) << endl;

   return 0;
}

詳しくは こちら を参照してください。

1
amirfg

あなたは戻り型の前に、一番初めにそれを入れたいのです。しかしほとんどのコンパイラはそれを無視します。それが定義されていて、コードのブロックが小さい場合、ほとんどのコンパイラはそれをインラインと見なします。

0
Jeremy Morgan