web-dev-qa-db-ja.com

ファンクターは実際には関数へのポインターよりも速いのですか?

スコット・マイヤーズによると、C++がCを凌ぐ領域の1つは、関数オブジェクトが関数ポインターよりも速いということです。これは、関数オブジェクトがインライン化され、速度が向上するためだと言います。

これについて2つの質問があります。

  1. 関数オブジェクトが実際にインライン化されていることをどのように検証できますか?これを実際に検証できますか?

  2. 関数オブジェクトのインライン化は、使用するコンパイラに依存しますか、それともすべてのコンパイラがこのように動作しますか?

58
user7140484

C++およびC標準は、コンパイラに自由の束を残します。コンパイラは、各命令間で10億まで自由にカウントできます。または、整数にプライム値が含まれている場合にのみカウントできます。

まともな「本物の」コンパイラーはこれを行いません。これは実装品質の問題です。

関数オブジェクトをstd::sortなどのようにインライン化することは、すべての実際のコンパイラーが行うことです。型情報にはインライン化が必要なコードが含まれているため、これらの場合にインライン化する必要があるものを検出するのは非常に簡単です。

関数ポインタを使用してこれを行うのは困難です。すべてがvoid*またはchar*ポインターに変換された関数ポインターでこれを行うのはさらに困難です。

この効果は、実際には、Cスタイルのqsortの呼び出しとC++スタイルのstd::sortの呼び出しがstd::sortに大きな利点をもたらすことです。

qsortは、ランダムに配置された整数をソートするというとんでもない単純な状況で、 here に示すように、std::sortの約2倍遅くなります。

実際のアセンブリコード出力の検査は主に詳細であり、ほとんど成果が得られない場合があります。具体的な実際の例を取り上げると、その影響が実際にどれほど大きいかがわかります。

std::sortqsortよりも大幅に高速化できるclang、gcc、およびMSVCの3つすべて。また、これは簡単な最適化であるため、インラインコールへの関数ポインターの最適化はそうではありませんが、qsortでこれよりも優れていない主要なコンパイラーが期待できます。

  1. 関数オブジェクトが実際にインライン化されていることをどのように確認できますか?これを実際に検証できますか?

確かに、最終的に発行されたアセンブラーコードを調べてください。

  1. インライン関数オブジェクトは、使用するコンパイラに依存しますか、それともすべてのコンパイラがそのように動作しますか?

コンパイラの実装と使用される最適化レベルに大きく依存します。
そのため、特定のコンパイラ(リンカー)がそのように動作するという保証はありません。

ただし、関数ポインターを介した呼び出しはインライン化できません。


彼によると、関数オブジェクトはインライン化されているため、速度が向上しています。

IMO "関数オブジェクトはインライン化されています"を読むと良いでしょう(または聞いたことがあるのですが、どこから引用されたのかわかりません):

関数オブジェクトインライン化可能関数ポインタを介した呼び出しはできません。

18

はい、関数オブジェクトはコードの高速化につながる可能性があります。しかし、それを確実にする唯一の方法はベンチマークです。

  1. documentation は次のように述べています。「 GCCは多くの理由で関数をインライン化できない場合があります。-Winlineオプションを使用して、関数がインライン化されていないかどうかを判断できます。 "

  2. もちろん、コンパイラ、バージョン、フラグなどに依存します。インライン化は逆効果になる場合があります(コードの膨張など)。したがって、各コンパイラは関数をインライン化するかどうかを決定する独自のルールセットを持っています。ちなみに、inlineキーワードは単なるヒントであり、 eigen などの一部のライブラリはインライン化を強制するのが困難です。

1
YvesgereY