Как сделать оптимизацию ветки для каждого кадра?

Предположим, у меня есть основной цикл, который обновляет разные вещи в кадре:

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

Могу ли я сделать это более дружественным для предсказателя ветки? Может ли предиктор ветвления определить, что каждый блок будет выполняться один раз в n кадры? Есть ли альтернатива для ветвления (сомнительно, предположим, что в блоках достаточно разная логика)?

Обратите внимание, что будет полная оптимизация, switch не имеет большого значения (если есть).

2

Решение

Как я прокомментировал выше, без какого-либо примера кода, я думаю, здесь будет сложно оказать какую-либо полезную помощь. Не могли бы вы опубликовать фрагмент кода, который показывает огромное количество пропущенных веток?

Я просто попробовал что-то вроде этого:

#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
1

Другие решения