Как проверить наличие проблем с порядком памяти в коде без блокировки / на основе атомного кода на x86/64?
Пробуя примеры из учебников по использованию тегов порядка памяти с атомарностью, я понял, что даже с std::memory_order_relaxed
примеры, подобные приведенному ниже, работают так же, как если бы использовались более сильные теги порядка памяти. По поиску я нахожу это, потому что x86 уже гарантирует относительно сильно упорядоченную модель памяти. Мой вопрос заключается в том, что при написании кода параллелизма на основе атомарного кода на платформе x86, как я должен знать, является ли написанный мною код "безопасным", даже если я испортил теги порядка памяти, он все еще работает?
под "безопасным" я подразумеваю, что будет работать так, как задумано, без автоматического сильного упорядочения памяти x86.
#include <atomic>
#include <thread>
#include <assert.h>
std::atomic<bool> x, y;
std::atomic<int> z;
void write_x_then_y()
{
x.store(true, std::memory_order_relaxed);
y.store(true, std::memory_order_relaxed);
}
void read_y_then_x()
{
while (!y.load(std::memory_order_relaxed));
if (x.load(std::memory_order_relaxed))
++z;
}
int main()
{
x = false;
y = false;
z = 0;
std::thread a(write_x_then_y);
std::thread b(read_y_then_x);
a.join();
b.join();
assert(z.load() != 0);
}
На x86 assert никогда не сработает, и вышеприведенный код ведет себя так, как если бы хранилище для y и загрузка y использовали семантику освобождения / получения.