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

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

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

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

В своем ответе он объясняет, что Intel Compiler (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];

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

Ответы на вопрос(6)

Ваш ответ на вопрос