Должен ли 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
является.
я думаю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
к атомной переменной и прошу об этом.
Есть много предположений, которые я сделал, пожалуйста, скажите мне, если что-то не так среди них.