TL: DR: Проблема здесь заключается в том, что вы только думаете о это как std::atomic_thread_fence(std::memory_order_seq_cst)
, но это не единственное, что делают заявления GNU C volatile asm
.
Да, очевидно, что существует барьер, создающий неприятный цикл задержки ожидания ожидания. Помните, что волатильный оператор asm
нельзя переупорядочить с помощью каких-либо других операторов C, а не только операций с памятью.
Godbolt
void loop_nomemclobber(int loops) {
do { // loop rearranged for simpler asm
asm volatile ("" : : : /* "memory" */);
} while (--loops > 0);
}
loop_nomemclobber:
.L3:
sub edi, 1
test edi, edi
jg .L3
ret
Мы до сих пор получить петлю, даже не заставляя всех достижимых памяти быть уточненный и рассматриваться как затирается. Таким образом, аргумент asm volatile
делает это не имеет ничего общего с клеем "memory"
.
int loops
является локальным с автоматическим хранением. Компилятор может доказать, что ничто (включая оператор asm) не имеет никакого способа определить, где оно может быть в памяти, поэтому оно не должно быть в памяти вообще.
Как глубоко ли процессор в состоянии предсказать, что есть шанс применить StoreLoad?
ЦП не ищет возможности изменить порядок памяти без причины! Переупорядочение происходит естественным образом (если не предотвращено с помощью MFENCE), потому что ЦП должен хранить буферные хранилища, пока не станет уверенным, что они не являются спекулятивными, а также хранилищами с кэшем. Таким образом, он помещает магазины в буфер хранилища, и в конечном итоге они фиксируют кеш.
Внутри процессора нет немного демона, говорящего «ага, вот еще один шанс сделать вещи сложными для Гильгамеза, может быть, я на самом деле обману его на этот раз с этим переупорядочением!"
Существует реальный вопрос здесь, и это , как далеко друг от друга две команды должны быть (по времени или по количеству insns, или число промежуточных нагрузок/магазинов) до того, как конкретный микроархитектуры Безразлично» t иметь достаточные ресурсы не по порядку для этого магазина, чтобы когда-либо буферизоваться до этой загрузки.
Я не знаю, но поскольку переупорядочение StoreStore не разрешено, хранилище кэш-миссий, критическая строка кэша не может сидеть там, ожидая получения доступа к линии кэша, пока выполняются миллионы других инструкций. Если ни одна из этих инструкций не была магазином.
Я не знаю ответа, но я считаю правдоподобным, что теоретически теоретически можно было бы запаздывать на миллионы циклов в Intel Haswell, возможно, ограничиваясь только алгоритмами справедливости аппаратных арбитражных механизмов, которые обрабатывают случай, когда несколько ядер бороться за доступ к одной и той же строке кэша.
Я забыл, что я читал о том, работает ли это современное оборудование Intel, или нет, но я думаю, что, возможно, магазин может уйти из ядра внешнего порядка, но все еще не привязан к кэшу L1. Вместо этого, это только в очереди магазина как магазин, который определенно произойдет. Это позволит магазинам кэширования избежать блокировки ввода новых инструкций в ROB. (Нагрузки должны исследовать буфер хранилища, чтобы сохранить правильное выполнение в одном ядре, но для этого не требуется, чтобы магазины также отслеживались ROB).
1) Возможно, в качестве побочного эффекта он не позволяет оптимизатору отказаться от «ненужной» модификации «петель» в противном случае. –
Что произойдет, если вы выберете его и скомпилируете с помощью функции -O3? Как код отличается от барьера на месте? –
Я вижу. Поэтому вы предполагаете, что существует барьер, потому что, в противном случае, он будет удален компилятором? Как насчет вопроса? Возможно, я не очень хорошо объяснил, что я имел в виду? – Gilgamesz