我想了解C++ 11的Relaxed Memory Ordering
。我的理解是:在C++中輕鬆的內存排序
This ordering guarantees that the ordering of operations on a
particular atomic variable doesn't change but ordering
of operations of different atomic variables can change. The ordering here is
within the same thread. For example,
Thread 1
operation A on atomic X
operation B on atomic Y
operation C on atomic Y
operation D on atomic X
Relaxed ordering guarantees that operation A will always happen-before
operation D and operation B will always happen-before operation C.
Having said that, the ordering of operations between X & Y can still change.
That is, suppose the original code was like above. One possible execution
order could be:
operation A on atomic X
operation D on atomic X
operation B on atomic Y
operation C on atomic Y
如果我的理解錯誤,請糾正我。
我在下面寫了一個示例代碼來測試Relaxed Memory Ordering
和預計assert
有時會失敗。但它永遠不會失敗。我建Visual Studio 2017
這一計劃,並與Intel(R) Core(TM) i7-6600U [email protected] 2.60GHz 2.80GHz
class RelaxedMemoryOrdering{
#define ARRAY_SIZE 4096
public:
static int var_array[ARRAY_SIZE];
RelaxedMemoryOrdering() {
for (int index = 0; index < ARRAY_SIZE; ++index) {
var_array[index] = 0;
}
sync1 = 0;
sync2 = 0;
sync3 = 0;
sync4 = 0;
sync5 = 0;
}
void thread1() {
sync1.store(1, std::memory_order_relaxed);
sync2.store(1, std::memory_order_relaxed);
sync3.store(1, std::memory_order_relaxed);
for (int index = 0; index < ARRAY_SIZE; ++index) {
var_array[index] = index + 1;
}
sync4.store(1, std::memory_order_relaxed);
sync5.store(1, std::memory_order_relaxed);
}
void thread2() {
while (!sync5.load(std::memory_order_relaxed)) {
;
}
assert(sync4.load(std::memory_order_relaxed) == 1);
for (int index = 0; index < ARRAY_SIZE; ++index) {
assert(RelaxedMemoryOrdering::var_array[index] == (index + 1));
}
assert(sync3.load(std::memory_order_relaxed) == 1);
assert(sync2.load(std::memory_order_relaxed) == 1);
assert(sync1.load(std::memory_order_relaxed) == 1);
}
void Test() {
std::thread t1(&RelaxedMemoryOrdering::thread1, this);
std::thread t2(&RelaxedMemoryOrdering::thread2, this);
t1.join();
t2.join();
}
private:
std::atomic_int sync1{0};
std::atomic_int sync2{0};
std::atomic_int sync3{0};
std::atomic_int sync4{0};
std::atomic_int sync5{0};
};
static void TestRelaxedMemoryOrdering() {
while (1) {
{
RelaxedMemoryOrdering rmo;
rmo.Test();
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}//while loop
}
int main()
{
TestRelaxedMemoryOrdering();
}
可能失敗的例子沒有圍欄:https://bartoszmilewski.com/2008/11/05/who-ordered-memory-fences-on-an-x86/ –