7

La documentazione per __assume dice "L'uso più comune di __assume è il caso predefinito di un'istruzione switch, come mostrato nell'esempio seguente.".Alcuni esempi di __assume che portano a un codice più veloce diverso da "nessun valore predefinito" nello switch?

  • C'è qualche altro caso in cui __assume può portare a un codice più efficiente (o anche diverso)?
  • Quando dentro se/else, il compilatore automaticamente "assume" ciò che è già noto a causa della condizione if?

Non sono stato in grado di trovare esempi non banali che mostrassero nessuno dei precedenti - spero che qualcun altro possa farlo.

risposta

7

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).

+0

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

+0

@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

Problemi correlati