カーネルで可能な呼び出しと不可能な呼び出しの違いは何ですか?カーネルソースコードの検索中に、次の文が見つかりました。
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
誰かがこれを説明できますか?
ベストアンサー1
これはGCCのコンパイラのヒントです。条件文でブランチを実行できるかどうかをコンパイラに通知するために使用されます。これは、コンパイラが最も一般的な結果に最も適した方法でコードを書くのに役立ちます。
これらは次のように使用されます。
if (likely(some_condition)) {
// the compiler will try and make the code layout optimal for the case
// where some_condition is true, i.e. where this block is run
most_likely_action();
} else {
// this block is less frequently used
corner_case();
}
慎重に使用する必要があります(つまり、実際の四半期分析の結果に基づいています)。間違ったプロンプトはパフォーマンスを低下させます(明らかに)。
を検索すると、コードを最適化する方法のいくつかの例を簡単に見つけることができますGCC __builtin_expect
。このブログ投稿gcc最適化:__builtin_expect例えば、分解について詳しく説明する。
実行できる最適化の種類は、プロセッサごとに異なります。一般的なアイデアは、コードがどこからでも分岐/ジャンプしない場合、プロセッサは通常コードをより速く実行することです。線形性が高く、分岐の予測可能性が高いほど、実行速度が速くなります。 (たとえば、深いパイプラインを持つプロセッサの場合は特にそうです。)
したがって、コンパイラは、可能性の高いブランチにジャンプが含まれないようにコードをエクスポートします(たとえば、ターゲットCPUがジャンプを好む場合など)。