// file: inc.cc
int inc_value(int* x) {
(*x)++;
//std::atomic ww;
//ww.load(std::memory_order_relaxed);
(*x)++;
return *x;
}
< /code>
Это генерирует следующую сборку для операции приращения: < /p>
g++ -S inc.cc -o inc.s -O3
addl $2, %eax
< /code>
После того, как я включил использование атомной переменной, я получил: < /p>
addl $1, (%rdi)
movl -4(%rsp), %eax
movl (%rdi), %eax
addl $1, %eax
movl %eax, (%rdi)
< /code>
Кажется, что расслабленная атомическая нагрузка работает как компилятор-фонд (точно так же, как asm < /strong> volatile (":::" memory ");), так что GCC не может переупорядочить инструкции вокруг него; < /p>
Я не знал: < /p>
[*]
x86-64 имеет сильную модель памяти TSO; Атомные операции не генерируют инструкции по блокировке/XCHG/MFENCE CPU-FENCE, работают только в качестве компилятора (за исключением SEQ_CST);
Согласно выше, GCC не должен переупорядочить+оптимизировать код, чтобы добавить $ 2, %EAX, подобно расслабленному, не требует эффекта; Но результат показывает, что GCC принимает расслабленную нагрузку в качестве компилятора-фонда, останавливает любое переупорядочение; Итак, у меня есть следующее вопрос: < /p>
- Для x86-64, всегда генерирует ли GCC полный компилятор-фон для атомной работы? Хотя это расслабленная операция; Кроме того, GCC генерирует перемещение к памяти вместо инструкции с перемещением в регистрацию (не имеет квалификации значения TMP в регистре), также подразумевает ли «атомнокомпилятор» также побочный эффект памяти для GCC, чтобы GCC сохраняет/нагрузку из памяти вокруг забора? Поскольку x86-64 имеет гарантии TSO, а расслабленный заказ принимается в качестве полного компилятора, он может заменить использование выпуска/приобретения/потребления.
Подробнее здесь: https://stackoverflow.com/questions/793 ... iler-fence
Мобильная версия