4

私が扱っているアプリケーションには、1 回の実行で 90% の確率で 1 つの分岐のみが実行されるという特性を持つ多数の if ステートメントがあります。

これで、次のようなことを行うことで、特定の CPU の単一の if ステートメントに対する分岐予測の影響をテストできます:-

#include <iostream>
#include <stdlib.h>

using namespace std;

int main() {
  int a;
  cin>>a;
  srand(a);
  int b;

  long count=0;

  for (int i=0; i<10000; i++) {
    for (int j=0; j<65535; j++) {
      b = rand() % 30 + 1;
      if (b > 15) // This can be changed to get statistics for different %-ages
        count += (b+10);
    }
  }

  cout << count <<"\n";
}

私の質問は、特定の CPU の実際の大規模なアプリケーションで、複数の if ステートメントを使用して分岐予測のスケーラビリティと影響をテストする方法はありますか?

基本的に、分岐の予測ミスがさまざまな CPU にどれだけのコストをかけているか、およびそれらがアプリケーションに与える影響を把握できるようにしたいと考えています。

4

1 に答える 1

4

ブランチの複雑さを考慮する必要があります。コンパイラは、CMOV (比較と移動) などのアーキテクチャ固有の操作コードを使用してブランチを削除する場合があります。

あなたの簡単なサンプルコード

if (b > 15)
    count += (b+10);

これが機械語にコンパイルされたコードです

;; assembly x86 FASM/NASM syntax

;; WITH branching
MOV ebx, [b] ;; b
MOV ecx, [count] ;; count
CMP ebx, 15 ;; if condition to set flags
JLE .skip ;; { branch/jump over the if body when less than or equal
LEA eax, [ecx + ebx + 10] ;; count + b+10
MOV [count], eax ;; store count
.skip: ;; } label after the if block

;; WITHOUT branching
MOV ebx, [b] ;; b
MOV ecx, [count] ;; count
LEA eax, [ecx + ebx + 10] ;; pre-calc avoiding the need to branch
CMP ebx, 15 ;; if condition to set flags
CMOVLE eax, ecx ;; make eax equal to ecx (current count) when less than or equal
            ;; avoiding the branch/jump
MOV [count], eax ;; store count

そのため、最適化コンパイラがコードをどのように最適化しているかを知らない限り、分岐予測のプロファイルを作成するのは少し難しくなります。マシン コードの出力をチェックしていて、多くの J[condition] ステートメントがあることがわかっている場合は、コメントに記載されているコード プロファイリング ツールを使用するだけで十分です。適切なアーキテクチャ デバッグ レジスタを使用せずに独自の分岐予測テストを実行しようとすると、上記で示した状況が発生します。

于 2012-09-10T18:04:59.730 に答える