Почему не может (или не )компилятор оптимизирует предсказуемый цикл сложения в умножение?

Это вопрос, который пришел в голову при чтении блестящего ответа Mysticial на вопрос:почему быстрее обрабатывать отсортированный массив, чем несортированный ?

Контекст для задействованных типов:

const unsigned arraySize = 32768;
int data[arraySize];
long long sum = 0;

В своем ответе он объясняет, что компилятор Intel (ICC )оптимизирует это:

for (int i = 0; i < 100000; ++i)
    for (int c = 0; c < arraySize; ++c)
        if (data[c] >= 128)
            sum += data[c];

... во что-то эквивалентное этому:

for (int c = 0; c < arraySize; ++c)
    if (data[c] >= 128)
        for (int i = 0; i < 100000; ++i)
            sum += data[c];

Оптимизатор распознает, что они эквивалентны, и поэтому меняет местами циклы , перемещая ветвь за пределы внутреннего цикла. Очень умно!

Но почему не делает этого?

for (int c = 0; c < arraySize; ++c)
    if (data[c] >= 128)
        sum += 100000 * data[c];

Будем надеяться, что Mysticial (или кто-то еще )сможет дать столь же блестящий ответ. Я никогда раньше не узнавал об оптимизации, обсуждаемой в этом другом вопросе, поэтому я очень благодарен за это.

125
задан Community 23 May 2017 в 12:26
поделиться