В кодовой базе есть макрос COMPILER_BARRIER
, определенный как __asm__ volatile("" ::: "memory")
. Цель макроса — предотвратить переупорядочивание операций чтения и записи через барьер компилятором. Обратите внимание, что это явно барьер компилятора, а не барьер памяти на уровне процессора.
В нынешнем виде это довольно переносимо, так как в AssemblerTemplate нет реальных инструкций по сборке, только volatile
и memory
клобер. Таким образом, пока компилятор соблюдает синтаксис расширенного ассемблера GCC, он должен работать нормально. Тем не менее, мне любопытно, как правильно выразить это в атомарном API С++ 11, если это возможно.
Следующее казалось правильным: atomic_signal_fence(memory_order_acq_rel);
.
Мои рассуждения таковы:
- Из
<atomic>
API толькоatomic_signal_fence
иatomic_thread_fence
не нуждаются в адресе памяти для работы. atomic_thread_fence
влияет на порядок памяти, который нам не нужен для барьера компилятора.- Клоббер
memory
в расширенной версии Asm не делает различий между чтением и записью, поэтому может показаться, что нам нужны семантика как получения, так и освобождения, поэтомуmemory_order_acq_rel
, по-видимому, требуется как минимум. memory_order_seq_cst
кажется ненужным, поскольку нам не требуется общий порядок потоков — нас интересует только последовательность инструкций внутри текущего потока.
Можно ли выразить эквивалент __asm__ volatile("" ::: "memory")
полностью переносимым с помощью C++11 atomics API? Если да, то является ли atomic_signal_fence
правильным API для использования? Если да, то какой аргумент порядка памяти подходит/требуется здесь?
Или я здесь в сорняках, и есть лучший способ подойти к этому?
atomic_signal_fence
гарантирует только порядок между потоком и обработчиком сигналов, работающим в том же потоке. Точно так жеatomic_thread_fence
применяется только к порядку между потоками. Если вы пытаетесь гарантировать порядок между двумя другими контекстами, то ни один из них не является переносимым. Например, в Windowsatomic_signal_fence
ничего делать не нужно, потому что Windows не поддерживает асинхронные сигналы. - person Ross Ridge   schedule 26.07.2016atomic_thread_fence
определяется в терминах атомарных операций над атомарными объектами, как это определено стандартом. Поэтому, если вы не используете типыstd::atomic
, ни одна из функций не будет работать. - person Ross Ridge   schedule 26.07.2016