2010-11-05 23 views

risposta

28

vi rimando alla sezione 10.5.3 della specifica, in cui si afferma:

Per i campi non-volatili, ottimizzazione tecniche che riordinare le istruzioni possono portare a inaspettati e risultati imprevedibili in multi- programmi filettati che accedono ai campi senza sincronizzazione come forniti dall'istruzione lock (§8.12). Queste ottimizzazioni possono essere eseguite dal compilatore, dal sistema di runtime o dall'hardware.Per campi volatili, quali riordino ottimizzazioni sono limitate:

Un di lettura di un campo di volatili si chiama una lettura instabile . Una lettura volatile ha "acquisisce la semantica"; vale a dire, è garantito prima di qualsiasi riferimento alla memoria che si verifica dopo nella sequenza di istruzioni.

A La scrittura di un campo volatile è denominata scrittura volatile. Una scrittura volatile ha la "semantica di rilascio" ; vale a dire, è garantito dopo qualsiasi riferimento di memoria prima dell'istruzione di scrittura nella sequenza dell'istruzione.

Queste limitazioni garantiscono che tutte le discussioni osserveranno volatili scritture eseguite da qualsiasi altro filo nell'ordine in cui sono stati eseguiti . Un'implementazione conforme non è necessaria per fornire un unico ordinamentototale di scritture volatili come visto da tutti i thread di esecuzione.

Leggi che con estrema attenzione se avete intenzione di fare sempre un campo volatile. Se non si dispone di completamente e completamente, comprendere tutte le implicazioni della semantica volatile, quindi non tentare di utilizzarli. Di solito è molto meglio usare un lucchetto, che ti dà automaticamente barriere di memoria sufficienti a garantire la semantica necessaria per l'acquisizione e il rilascio. Ricorda, le serrature sono molto costose solo quando vengono contese.

+2

bene, è stata una grande spiegazione. (Y) –

+0

@Shimmy: sei perfettamente in grado di trovare le specifiche senza il mio aiuto. –

+0

Ma non spec 10.5.3 :) – Shimmy

4

MSDN riassumerà meglio di me ....

"La parola chiave volatile indica che un campo potrebbe essere modificato da più thread che stanno eseguendo allo stesso tempo. I campi che vengono dichiarati volatili non sono soggetti a ottimizzazioni del compilatore che presuppongono l'accesso da un singolo thread, in modo da garantire che il valore più aggiornato sia sempre presente nel campo. "

http://msdn.microsoft.com/en-us/library/x13ttww7(v=VS.100).aspx

7

volatile viene utilizzato per una variabile che può cambiare senza la vostra azione mentre il codice è in esecuzione. Indica al compilatore di scrivere l'assembly in modo tale da non mettere mai in cache la variabile, ma per essere sicuro di leggerlo prima di ogni utilizzo.

Un esempio di qualcosa che sarebbe volatile sarebbe un registro hardware che il tuo codice ha mappato in memoria e sta leggendo per determinare quando viene impostato un flag. L'hardware può impostare il valore mentre il codice è in esecuzione e senza utilizzare la parola chiave volatile non si noterà questa modifica poiché l'assembly non verrebbe mai effettivamente controllato il valore.

6

volatile è un suggerimento per il compilatore (e compilatore NGEN/JIT) che il valore di questa variabile può cambiare in qualsiasi momento, e quindi ottimizzazioni attorno accesso alla variabile cache il valore localmente volatili disabilitato .

consideri il codice seguente:

If (UserName == "") 
    // do something 
If (UserName == "Fred") 
    // do something 

Se volatile non era presente, il compilatore potrebbe generare IL dove memorizza il riferimento sulla pila per il primo confronto e che riutilizza per il secondo. Tuttavia, aggiungendo volatile dice al compilatore che il riferimento potrebbe essere cambiato da un altro thread, forzandolo quindi a generare IL che non riutilizzerà la copia dello stack dal primo confronto.

+0

hmm, vuoi dire, ogni volta che si accede a una variabile genererà un nuovo IL invece di usare la copia dello stack, giusto? –

+0

Sì, se è presente volatile, il compilatore genererà nuove istruzioni IL per ottenere il valore del campo per ciascun accesso al campo. Se volatile non è presente, il forzato potrebbe saltare quella IL per il secondo e il successivo accesso pieno. –

+0

Vale la pena notare che questo è necessario solo con le applicazioni multi-thread. Un thread potrebbe leggere UserName, quindi la CPU passa all'altro thread, aggiorna UserName, quindi la CPU torna indietro. il primo thread ora ha una vecchia versione di UserName a meno che non lo ricontrolli. –

2

Non è altro che dice di compilatore che questa variabile cambierà il suo valore in qualsiasi momento per mezzo di nulla e compilatore non dovrebbe fare alcuna ipotesi su questa variabile.

Normalmente il compilatore presumerà che alcune variabili saranno costanti durante il runtime. Ciò potrebbe causare errori nel controllo ripetuto di un valore del registore . Perché il valore del registro può essere modificato da . Quindi per questo tipo di variabili deve essere dichiarato 'volatile' e deve essere verificato ogni volta che appare nel codice senza alcuna ipotesi.

Problemi correlati