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.