x86 согласован с кешем даже через несколько сокетов (как и все другие реальные ISA, которые вы можете запускать через std::thread
). Модель упорядочения памяти x86 - это программный порядок + буфер хранения с пересылкой в хранилище.
Формальная модель: Лучшая модель памяти x86: x86-TSO . Неофициально: http://preshing.com/20120930/weak-vs-strong-memory-models/
Отсутствие согласованности определенно не ваша ошибка. Как только хранилище фиксирует кэш L1d в одном ядре, никакое другое ядро не может загрузить старое значение. (Поскольку все их копии строки были признаны недействительными, поэтому ядро, выполняющее модификацию, может иметь исключительное владение: MESI .)
Почти наверняка p2 читает общую память перед p1 пишет это. Coherence не создает синхронизацию самостоятельно. Если p1 и p2 оба подключаются к общей памяти асинхронно, ничто не мешает p2 читать до записи p1.
Вам нужны какие-то данные флаг готовности, который проверяет p2 с помощью std::memory_order_acquire
перед чтением указателя. Или просто вращайте при загрузке указателя, пока не увидите значение, отличное от NULL.
(Используйте mo_acquire
при загрузке указателя atomi c, чтобы избежать переупорядочения во время компиляции или переупорядочения во время выполнения при не x86, с вещами, к которым вы обращаетесь позже, используя этот указатель. Или для использования указателя понадобится только mo_consume
, но компиляторы усиливают его до mo_acquire
. Это нормально для x86; приобретение в любом случае бесплатно.)