1. ホーム
  2. c

[解決済み] GCCのif else文における__builtin_expectの利点は何ですか?

2022-04-23 22:32:42

質問

を発見しました。 #define を使用している。 __builtin_expect .

ドキュメント と書かれています。

内蔵された機能。 long __builtin_expect (long exp, long c)

を使用することができます。 __builtin_expect を使用すると、コンパイラに分岐を提供することができます。 の予測情報です。一般に、実際の プロファイルのフィードバックに使用されます ( -fprofile-arcs というのも、プログラマは は、自分のプログラムが実際にどのように動作するかを予測することが苦手なことで知られています。 しかし、このデータを収集するのが難しいアプリケーションもあります。

の値を返します。 exp であり、積分値である必要があります。 式で表されます。この組み込みのセマンティクスは、以下のように期待されています。 exp == c . 例えば

      if (__builtin_expect (x, 0))
        foo ();

を呼び出すことは想定していないことを示します。 foo を想定しているので x はゼロになる。

では、なぜ直接使用しないのか。

if (x)
    foo ();

という複雑な構文ではなく __builtin_expect ?

解決方法は?

から生成されるアセンブリコードを想像してください。

if (__builtin_expect(x, 0)) {
    foo();
    ...
} else {
    bar();
    ...
}

みたいな感じでいいんでしょうかね。

  cmp   $x, 0
  jne   _foo
_bar:
  call  bar
  ...
  jmp   after_if
_foo:
  call  foo
  ...
after_if:

というような順序で指示が並んでいるのがわかります。 bar の方が先です。 foo の場合(Cコードとは対照的)。ジャンプはすでにフェッチされた命令をスラッシュするので、これはCPUパイプラインをよりよく利用することができます。

ジャンプが実行される前に、その下の命令( bar の場合)はパイプラインにプッシュされます。そのため foo が発生する可能性は低く、ジャンプも発生しないので、パイプラインをスラッシングする可能性は低い。