Я запускаю поток, который выполняется до тех пор, пока не будет установлен флаг.
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
.
Я думаю, что цикл while()
может быть преобразован как бесконечный оператор 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();
...
}
Если атом не подразумевает изменчивость, тогда я думаю, что код может быть даже преобразован как это в худшем случае.
void f() {
if(stop.load(std::memory_order_{relaxed,acquire})) return;
while(true) {
do_the_job();
}
}
Там никогда не будет такой безумной реализации, но я думаю, это все еще возможная ситуация. Я думаю, что единственный способ предотвратить это - поставить volatile
на атомную переменную и спросить об этом.
Есть много догадок, которые я сделал, скажите, пожалуйста, если что-то не так.