Si consideri il seguente codice, compilato con l'interruttore /Ox
:
if (1) {
printf("live code\n");
} else {
printf("dead code\n");
}
L'ottimizzatore ottimizzerà via il else
. Consideriamo ora:
int x = 1;
if (x == 1) {
printf("live code\n");
} else {
printf("dead code\n");
}
L'ottimizzatore sarà ancora una volta di ottimizzare via la else
. Considera anche:
int x = 1;
__assume(x != 1);
if (x == 1) {
printf("live code\n");
} else {
printf("dead code\n");
}
L'ottimizzatore ottimizzerà via la if
questa volta - in modo non corretto così.
Per provare, costruire un programma di test in modalità di rilascio (con le opzioni /Ox
e /Zi
) e guardare l'assembly generato (Alt+8
in Visual Studio.)
Ora consideriamo il sopra if/else
condizioni in fase di sperimentazione in un inline metodo. In determinati contesti, il programmatore può sapere che il metodo inline viene chiamato con un valore particolare e l'ottimizzatore potrebbe non aver realizzato questo fatto. L'utilizzo di __assume
a livello di chiamante nel modo illustrato sopra, appena prima che venga chiamato il metodo inline, può in teoria aiutare l'ottimizzatore.
Da Optimization Best Practices:
__assume è stato in Visual C++ per molteplici versioni, ma è diventato molto più usabile in Visual C++ 2005. Con __assume, uno sviluppatore può dire al compilatore di fare ipotesi su il valore di alcune variabili.
Ad esempio __assume (a < 5); dice all'ottimizzatore che a quella riga di codice la variabile a è inferiore a 5. Di nuovo questa è una promessa al compilatore. Se a è in realtà 6 a questo punto nel programma , il comportamento del programma dopo il compilatore è ottimizzato, potrebbe non essere quello che si dovrebbe ottenere . __assume è più utile prima di per passare istruzioni e/o espressioni condizionali .
Ci sono alcune limitazioni a __assume. Innanzitutto, come __restrict, è solo un suggerimento, quindi il compilatore è libero di ignorarlo.Inoltre, __assume attualmente funziona solo con variabili disuguaglianze rispetto alle costanti. È non propagare le disuguaglianze simboliche , ad esempio, si supponga (uno < b).
Poiché __assume è documentato come suggerimento del compilatore, penserei che il comportamento che si mostra (l'ottimizzazione della clausola else) sia un bug. Sei riuscito a vederlo con un solo compilatore e l'hai visto con le versioni più recenti di msvc? – Garen
@Garen, il comportamento mostrato è coerente con la documentazione, perché __assumi che sia un bug? Sentiti libero di provarlo con il tuo gusto MSVC preferito, IIRC sopra è stato testato con VC2010. – vladr