2

フレームごとにさまざまなものを更新するメイン ループがあるとします。

int currentFrame = frame % n;
if ( currentFrame == 0 )
{
   someVar = frame;
}
else if ( currentFrame == 1 )
{
   someOtherVar = x;
}
...
else if ( currentFrame == n - 1 )
{
   someMethod();
}

分岐予測子にとってより使いやすくすることはできますか? 分岐予測子は、各ブロックがnフレームごとに 1 回実行されると判断できますか? ブランチに依存しない代替手段はありますか (疑わしい、ブロックには十分に異なるロジックが含まれていると仮定します)。

完全な最適化がオンになることに注意してくださいswitch。大きな違いはありません (もしあれば)。

4

1 に答える 1

1

上でコメントしたように、コード例がないため、ここで役立つヘルプを提供するのは難しいと思います。膨大な数のブランチ ミスを示すコード スニペットを投稿していただけますか?

私はちょうどこのようなことを試しました:

#include <cstdlib>

__attribute__ ((noinline)) void frame(const int frame) // to prevent automatic unrolling
{
  const int n = 10;
  static int someVar = rand();
  static int someOtherVar = rand();

  const int currentFrame = frame % n;

  if (currentFrame == 0) {
    someVar = frame;
  } else if (currentFrame == 1) {
    someOtherVar += frame;
  } else if (currentFrame == 2) {
    someOtherVar -= someOtherVar;
    someVar = someOtherVar;
  } else if (currentFrame == 3) {
    someVar -= someOtherVar;
  } else if (currentFrame == 4) {
    someVar -= someOtherVar;
    someOtherVar *= someOtherVar;
  } else if (currentFrame == 5) {
    someOtherVar /= someVar + frame;
  } else if (currentFrame == 6) {
    someVar *= someOtherVar - frame;
  } else if (currentFrame == 7) {
    someOtherVar += someVar / (someOtherVar + 1);
  } else if (currentFrame == 8) {
    someVar -= someOtherVar * someVar;
  } else if (currentFrame == n - 1) {
    someOtherVar = frame;
    someVar = frame + 1;
  }
}

int main(int argc, char** argv)
{
  int iterations = 100000000;
  if (argc > 1) {
    iterations = std::atoi(argv[1]);
  }

  for (int i = 0; i < iterations; ++i) {
    frame(i);
  }

  return 0;
}

しかし、それはあなたの調査結果を再現していません:

Performance counter stats for './a.out 100000000':

        591.088374      task-clock (msec)         #    0.999 CPUs utilized          
                60      context-switches          #    0.102 K/sec                  
                5      cpu-migrations            #    0.008 K/sec                  
              272      page-faults               #    0.460 K/sec                  
    1,665,803,234      cycles                    #    2.818 GHz                     [50.25%]
  <not supported>      stalled-cycles-frontend  
  <not supported>      stalled-cycles-backend   
    3,741,605,478      instructions              #    2.25  insns per cycle         [75.14%]
    1,050,201,459      branches                  # 1776.725 M/sec                   [75.14%]
            11,115      branch-misses             #    0.00% of all branches         [74.64%]

      0.591689393 seconds time elapsed
于 2014-05-07T14:59:44.333 に答える