よく知られているlikely
およびunlikely
マクロは、if
が通常入力されるかスキップされるかをコンパイラーに知らせるのに役立ちます。これを使用すると、パフォーマンスが(かなりマイナーに)改善されます。
私は最近それらを使い始めました、そしてそのようなヒントがどれくらいの頻度で使われるべきかわかりません。現在、エラーチェックif
sで使用しています。通常、unlikely
とマークされています。例えば:
mem = malloc(size);
if (unlikely(mem == NULL))
goto exit_no_mem;
大丈夫のようですが、エラーチェックif
sが頻繁に発生するため、上記のマクロが使用されます。
私の質問は、すべてのエラーチェックlikely
にunlikely
マクロとif
マクロを含めるのは多すぎるのですか?
その間、他にどのような場所がよく使用されますか?
私の現在の使用方法では、リアルタイムサブシステムから抽象化するライブラリにあるため、プログラムはRTAI、QNX、その他の間で移植可能になります。そうは言っても、ほとんどの関数はかなり小さく、1つまたは2つの他の関数を直接呼び出します。多くはstatic inline
関数。
つまり、まず第一に、これは私がプロファイリングできるアプリケーションではありません。これはスタンドアロンアプリケーションではなくライブラリであるため、「ボトルネックを特定する」ことは意味がありません。
第二に、それは「これがありそうもないことを知っている、私はコンパイラーにそれを伝えた方がよい」のようなものです。私は積極的にif
を最適化しようとはしていません。
それでコードを汚染しようとするほどひどいパフォーマンスが必要ですか?マイナーな最適化です。
上記のすべてにyes
と答えられない限り、このようなことを気にしないでください。
編集:編集に応じて。プロファイルできない場合でも、通常はホットスポットを推定できます。誰もが呼び出すメモリ割り当て関数は、特にライブラリ全体で機能するためにマクロを1回だけ使用する必要があるため、良い候補です。
X86/x64向けに作成している場合(20年前のCPUを使用していない場合)、__ builtin_expect()を使用してもパフォーマンスはほとんど向上しません。その理由は、最近のx86/x64 CPU(Atomについては100%確実ではない))には動的分岐予測があるため、基本的にCPUはより頻繁に実行される分岐について「学習」するためです。確かに、この情報は限られた数のブランチについてのみ保存できますが、可能なケースは2つだけです。(a)これが「頻繁に使用される」ブランチである場合、プログラムはその動的ブランチ予測から恩恵を受け、 (b)これは「まれな」ブランチであり、そのようなまれなブランチの予測ミスによる実際のパフォーマンスヒットは実際には見られません(ブランチの予測ミスの20 CPUサイクルは、ブルームーンで一度発生したとしても、それほど悪くはありません)。
注意:これは、現代のx86/x64でブランチの予測ミスの重要性が低くなったという意味ではありません。ジャンプとジャンプの可能性が50-50のブランチでは、ペナルティ(IIRC 10-20 CPUサイクル)が発生するため、内部ループではブランチがまだ避ける必要があります。 x86/x64での__builtin_expect()の重要性は、主に動的な分岐予測のために減少しました(IIRC、約10〜15年前など)。
NB2:x86/x64、YMMV以外の他のプラットフォーム用。