2010-09-27 11 views
5

C'è qualche ragione per cui il compilatore non può ottimizzare le seguenti istruzioni 2 in main anche se ho attivato completamente l'ottimizzazione in Visual C++? Qualche effetto collaterale per accedere a una variabile int in memoria?Perché il compilatore non può ottimizzare questi 2 estratti?

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    volatile int pleaseOptimizeMeOut = 100; 

    (pleaseOptimizeMeOut); 

    return 0; 
} 

risposta

16

Essa non è in grado di ottimizzare fuori perché si è dichiarata la variabile di essere volatile. Carichi e archivi a volatile oggetti qualificati fanno parte degli effetti "esternamente visibili" della macchina astratta C.

(A proposito, ci sono sacco di effetti collaterali quando si accede una variabile in memoria, è possibile aggiornare le cache di memoria hardware tra cui il TLB, e forse anche causare errori di pagina E la memoria il processo è in esecuzione in potenza. essere snoopizzati da un altro processo, come un debugger).

+5

Questo effetto è un po 'il "punto" di 'volatile'. – SingleNegationElimination

5

Su alcuni computer, l'I/O del dispositivo è modellato come lettura/scrittura della memoria. Questo è il tipo di situazione quando volatile è usato correttamente ... dice esplicitamente al compilatore di non presumere che le operazioni variabili non siano importanti o possano essere ottimizzate ....

8

volatile dice esplicitamente al compilatore di non ottimizzare per quella variabile.

4

Altre risposte hanno sottolineato l'importanza di volatile qui e non ho nulla da aggiungere a questo. Tuttavia, voglio dire quanto sia importante che un tale costrutto esista, perché è utile. Dalla mia esperienza di progettazione hardware, molte volte l'interfaccia tra una CPU e un blocco logico in HW si basa su scritture e letture di memoria. Ciò significa che quando una CPU legge un registro dall'HW, accade qualcosa (ad esempio, l'interruzione cancella, anticipa le code e molte altre opzioni).

Ora, una volta che si esegue l'accesso al pleaseOptimizeMeOut, dal momento che è volatile il compilatore solo assume si potrebbe avere fatto solo per l'effetto collaterale, quindi sarebbe assolutamente sbagliato per ottimizzarlo. Supponiamo che la variabile sia mappata su una coda HW e che tu volessi semplicemente far avanzare la coda senza averne effettivamente preso un valore.

Detto questo, mappare le variabili ai registri durante la lettura ha effetti collaterali è IMHO non una buona pratica, e sarebbe meglio incapsularlo con una chiamata di funzione, esattamente per il motivo che dimostra la tua domanda - in alcuni casi è confuso.

Mappare le variabili ai registri senza effetti secondari è molto utile e ampiamente utilizzato, tuttavia.

Problemi correlati