フラグが設定されるまで実行されるスレッドを実行しています。std :: atomicは揮発性であるべきですか?
std::atomic<bool> stop(false);
void f() {
while(!stop.load(std::memory_order_{relaxed,acquire})) {
do_the_job();
}
}
コンパイラがこのようなループを展開できるかどうかは疑問です(私は起こりたくありません)。
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
}
}
ボラティリティとアトミック性は直交していると言われていますが、少し混乱しています。コンパイラはアトミック変数の値をキャッシュしてループを展開することはできますか?コンパイラがループを展開することができる場合、私はvolatile
をフラグに入れなければならないと確信しています。
volatile
を入力してください。
あいまって申し訳ありません。私は(私が)並べ替えが何であるかを理解しており、何がmemory_order_*
を意味するのかを理解しており、私は完全に理解していると確信していますvolatile
です。
ループはif
のように無限にループすると思います。
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();
...
}
与えられたメモリの注文がアトミック負荷を通過して移動されることから、配列決定、前の操作を防ぐことはできませんので、私はそれが揮発せずにいた場合、それは再配置することができると思います。
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();
...
}
アトミックにvolatileが含まれていない場合、コードは最悪の場合でもこのように変換される可能性があります。
このような非常識な実装は決してありませんが、それでも状況は可能です。私はこれを防ぐための唯一の方法は、volatile
を原子変数に置き、それについて尋ねることです。
私が作った推測はたくさんありますが、間違っているかどうか教えてください。
私はそうは思わない。最近、 'std :: atomic'のためにたくさんのことを見ましたが、誰もそれはすべきではないと言いました。私は、クラス内にはどこかに「揮発性の」変数があると思う。 – Nick
[同時実行性:C++ 11メモリモデルでのアトミックおよび揮発性]の可能な複製(http://stackoverflow.com/questions/8819095/concurrency-atomic-and-volatile-in-c11-memory-model) –
いいえ、それは揮発性ではありません。 –