Si consideri il seguente, semplice programma (adattato da this question):Perché questo programma non è ottimizzato?
#include <cstdlib>
int main(int argc, char** argv) {
int mul1[10] = { 4, 1, 8, 6, 3, 2, 5, 8, 6, 7 }; // sum = 50
int mul2[10] = { 4, 1, 8, 6, 7, 9, 5, 1, 2, 3 }; // sum = 46
int x1 = std::atoi(argv[1]);
int x2 = std::atoi(argv[2]);
int result = 0;
// For each element in mul1/mul2, accumulate the product with x1/x2 in result
for (int i = 0; i < 10; ++i) {
result += x1 * mul1[i] + x2 * mul2[i];
}
return result;
}
Credo che sia funzionalmente equivalente alla seguente:
#include <cstdlib>
int main(int argc, char** argv) {
int x1 = std::atoi(argv[1]);
int x2 = std::atoi(argv[2]);
return x1 * 50 + x2 * 46;
}
Eppure clang 3.7.1, gcc 5.3 e icc 13.0.1 sembrano essere in grado per rendere tale ottimizzazione, anche con -Ofast
. (Nota come l'assemblaggio generato è molto diverso tra i compilatori!). Tuttavia, quando si rimuovono mul2
e x2
dall'equazione, clang è in grado di eseguire un'ottimizzazione simile, anche con -O2
.
Cosa impedisce a entrambi i compilatori di ottimizzare il primo programma nel secondo?
@buttiful buttefly In generale il funzionamento x1 * mul1 [i] può risultare in overflow, –
Sono sorpreso che clang sia in grado di ottimizzare il ciclo quando si rimuove 'x2 * mul2 [i]' dall'equazione. Personalmente ritengo che non ci si debba aspettare nulla dall'ottimizzatore del compilatore; tutto ciò che viene ricevuto è un bonus! – iammilind
L'overflow di @vlad è UB, quindi si può presumere che non si verifichi durante l'ottimizzazione. – Yakk