Dlaczego kompilator nie może (lub nie) zoptymalizować przewidywalnej pętli dodawania do mnożenia?

To pytanie przyszło mi na myśl podczas czytania genialnej odpowiedzi przezMistyczny do pytania:dlaczego szybsze jest przetwarzanie posortowanej tablicy niż niesortowanej tablicy?

Kontekst dla zaangażowanych typów:

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

W swojej odpowiedzi wyjaśnia, że ​​Intel Compiler (ICC) optymalizuje to:

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

... w coś równoważnego:

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

Optymalizator uznaje, że są one równoważne i dlatego sąwymiana pętli, przesuwając gałąź poza wewnętrzną pętlę. Bardzo mądry!

Ale dlaczego tego nie robi?

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

Mam nadzieję, że Mysticial (lub ktokolwiek inny) może dać równie błyskotliwą odpowiedź. Nigdy wcześniej nie dowiedziałem się o optymalizacjach omawianych w tym innym pytaniu, więc jestem za to bardzo wdzięczny.

questionAnswers(6)

yourAnswerToTheQuestion