Как работает следующий код для слабой модели памяти, такой как ARM?
Примечание: я знаю, что порядок памяти относится только к многоядерным потокам, и что приведенный ниже код работает только в одном ядре, однако все еще есть вопросы ниже.
std::atomic_bool a {false};
std::atomic_bool b {false};
void signal_handler(int)
{
if (b.load(std::memory_order_relaxed))
{
std::atomic_signal_fence(std::memory_order_acquire);
assert(a.load(std::memory_order_relaxed));
}
}
int main()
{
std::signal(SIGINT, &signal_handler);
a.store(true, std::memory_order_relaxed);
std::atomic_signal_fence(std::memory_order_release);
b.store(true, std::memory_order_relaxed);
}
std::atomic_signal_fence
гарантирует только порядок на компиляторе.
Вопрос 1
Это то, что я понимаю: неупорядоченное выполнение может переупорядочить a.store()
и b.store()
, то есть буфер буфера может содержать b == true
, а a
все еще не выполняется (все еще a == false
). Если в этот момент обработчик сигнала запускается, то утверждение не будет выполнено (чтение значения из буфера хранилища, пересылка хранилища). Я знаю, как это не могло произойти в x86, так как магазины не переупорядочены, но не уверен, как это работает на ARM. Как процессор может убедиться, что обработчик сигнала видит код последовательно?
Вопрос 2
В многопоточной среде кода, если не используются барьеры памяти, могут ли буферы памяти быть сброшены в кэш-память из строя? Я предполагаю, что он может быть очищен не по порядку, в противном случае не потребуется никаких барьеров памяти, однако, когда я читаю определение Выполнение вне порядка , он говорит: «Процессоры OoOE заполняют эти« слоты »во времени». с другими инструкциями, которые готовы, затем измените порядок результатов в конце, чтобы создать впечатление, что инструкции были обработаны как обычно. " Не уверен, что ссылка ссылается только на x86, который следует модели сильной памяти.