Sto eseguendo un thread che viene eseguito finché non viene impostato un flag.Dovrebbe essere std :: atomic volatile?
std::atomic<bool> stop(false);
void f() {
while(!stop.load(std::memory_order_{relaxed,acquire})) {
do_the_job();
}
}
Mi chiedo se il compilatore può srotolare il ciclo come questo (non voglio che accada).
void f() {
while(!stop.load(std::memory_order_{relaxed,acquire})) {
do_the_job();
do_the_job();
do_the_job();
do_the_job();
... // unroll as many as the compiler wants
}
}
Si dice che la volatilità e atomicità sono ortogonali, ma io sono un po 'confuso. Il compilatore è libero di memorizzare nella cache il valore della variabile atomica e srotolare il ciclo? Se il compilatore può srotolare il ciclo, allora penso di dover mettere volatile
alla bandiera, e voglio essere sicuro.
Devo inserire volatile
?
Mi dispiace per essere ambiguo. Io (suppongo che io) capisco cosa sia il riordino e cosa significhi memory_order_*
s, e sono sicuro di capire appieno cosa sia lo volatile
.
Penso che il ciclo while()
possa essere trasformato come un infinito if
dichiarazioni come questa.
void f() {
if(stop.load(std::memory_order_{relaxed,acquire})) return;
do_the_job();
if(stop.load(std::memory_order_{relaxed,acquire})) return;
do_the_job();
if(stop.load(std::memory_order_{relaxed,acquire})) return;
do_the_job();
...
}
Dal momento che i dati degli ordini di memoria non impediscono le operazioni di sequenza-prima di essere spostato oltre il carico atomica, penso che possa essere ridefinita se è senza volatile.
void f() {
if(stop.load(std::memory_order_{relaxed,acquire})) return;
if(stop.load(std::memory_order_{relaxed,acquire})) return;
if(stop.load(std::memory_order_{relaxed,acquire})) return;
...
do_the_job();
do_the_job();
do_the_job();
...
}
Se l'atomica non implica volatile, quindi penso che il codice può essere anche trasformato in questo modo al caso peggiore.
void f() {
if(stop.load(std::memory_order_{relaxed,acquire})) return;
while(true) {
do_the_job();
}
}
Non ci sarà mai un'implementazione folle, ma immagino sia ancora una situazione possibile. Penso che l'unico modo per evitare questo è di mettere volatile
alla variabile atomica e sto chiedendo su di esso.
Ci sono molte supposizioni che ho fatto, per favore dimmi se c'è qualcosa di sbagliato in loro.
Io non la penso così. Ho guardato molto per 'std :: atomic' ultimamente, ma nessuno ha detto che dovrebbe essere. Immagino che all'interno della classe ci sia una variabile 'volatile' da qualche parte. – Nick
Possibile duplicato di [Concorrenza: atomico e volatile nel modello di memoria C++ 11] (http://stackoverflow.com/questions/8819095/concurrency-atomic-and-volatile-in-c11-memory-model) –
No, non dovrebbe essere volatile. –