2010-12-13 16 views
16

Ho trovato un articolo del 2001 su Dr Dobbs: volatile - Multithreaded Programmer's Best Friend. Ho sempre trovato un po 'inutile' volatile '- almeno come un qualificatore sulle variabili - in quanto l'accesso alle variabili condivise tra i thread passa comunque attraverso una sorta di strato di libreria.Conseguenza delle prestazioni delle funzioni membro volatile

Tuttavia, contrassegnare le istanze di classe e i metodi, come "volatili" per indicare il grado di sicurezza del thread come illustrato nell'articolo, sembra molto convincente.

Per riassumere l'articolo in fretta, l'idea centrale è potrebbe dichiarare una classe come questa:

struct SomeObject { 
    void SingleThreadedMethod(); 
    void Method(); 
    void Method() volatile; 
}; 

E poi, le istanze della classe, come questo:

// An object that will only be accessed from a single thread. 
SomeObject singleThreaded; 
// An objecect that will be accessed from multiple threads. 
volatile SomeObject sharedObject; 

sharedObject.SingleThreadedMethod(); //this will be an compile error 
sharedObject.Method(); // will call the volatile overload of Method 
singleThreaded.Method(); // would call the non volatile overload of Method. 

L'idea è che metodi come "Method() volatile" sarebbero implementati:

void SomeObject::Method() volatile { 
    enter_critical_section(); 
    const_cast<Method*>(this)->Method(); 
    leave_critical_Section(); 
} 

Ovviamente puntatori intelligenti può automatizzare il processo atomic-lock-and-cast-to-non-volatile - il punto è che il qualificatore volatile può essere usato, nel suo uso previsto, per marcare i membri della classe e le istanze per indicare come saranno usati da più thread e quindi ottenere il compilatore per dire allo sviluppatore quando i metodi single-thread (non volatile) vengono chiamati su un oggetto volatile, o anche per selezionare automaticamente la versione thread-safe.

La mia domanda su questo approccio è: quali sono le implicazioni di prestazioni dei metodi qualificati "volatili"? Il compilatore è costretto ad assumere che tutte le variabili a cui si accede in una funzione volatile debbano essere considerate volatili e quindi escluse dalle opportunità di ottimizzazione? Le variabili locali saranno escluse dall'ottimizzazione? Se così fosse, ciò potrebbe rappresentare un notevole ostacolo alle prestazioni per qualsiasi funzione di membro qualificato volatile.

+0

"è il compilatore costretti a supporre che tutte le variabili a cui si accede in una funzione volatile devono essere trattati come volatile e quindi esclusi dalla opportunità di ottimizzazione" I pensateci: il compilatore è tenuto a caricare dalla memoria il puntatore "this" ogni volta che l'oggetto viene toccato. Tuttavia, le variabili locali non dovrebbero essere influenzate. –

+1

Alcuni post correlati: http://stackoverflow.com/questions/2491495, http://stackoverflow.com/questions/2479067 – ronag

+0

Non ho "preferito" molte domande, ma ho preferito questo. Ottima domanda –

risposta

10
  • No, le variabili locali non verranno considerate volatili in un metodo volatile, praticamente allo stesso modo in cui le variabili locali non vengono considerate const in un metodo const.
  • Tutti i membri della classe saranno trattati come volatili all'interno del metodo volatile, più o meno allo stesso modo in cui tutti i membri non modificabili sono trattati const in un metodo const. Non esiste un equivalente di mutabile per volatile.
  • this non sarà un puntatore volatile, quindi l'accesso non lo caricherà dalla memoria ogni volta. Tuttavia this sarà un puntatore a volatile, il che significa che *this viene trattato come volatile
+2

Questa sembra essere l'interpretazione più coerente delle regole. –

Problemi correlati