Вычисления оптимизируются, только если переменная, обновляемая в цикле, является локальной - PullRequest
0 голосов
/ 14 января 2019

Для следующей функции код с оптимизацией векторизован, а вычисления выполняются в регистрах (возвращаемое значение возвращается в eax). Сгенерированный машинный код, например, здесь: https://godbolt.org/z/VQEBV4.

int sum(int *arr, int n) {
  int ret = 0;
  for (int i = 0; i < n; i++)
    ret += arr[i];
  return ret;
}

Однако, если я сделаю переменную ret глобальной (или параметр типа int&), векторизация не используется, и компилятор сохраняет обновленные значения ret в каждой итерации в памяти. Машинный код: https://godbolt.org/z/NAmX4t.

int ret = 0;

int sum(int *arr, int n) {
  for (int i = 0; i < n; i++)
    ret += arr[i];
  return ret;
}

Я не понимаю, почему оптимизации (векторизация / вычисления в регистрах) в последнем случае запрещены. Нет потоков, даже приращения не выполняются атомарно. Более того, это поведение кажется одинаковым для всех компиляторов (GCC, Clang, Intel), поэтому я считаю, что для этого должна быть какая-то причина.

1 Ответ

0 голосов
/ 14 января 2019

Если ret не локально, а глобально, arr может иметь псевдоним ret, уменьшая возможность оптимизации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...