我有类似的东西:
if (f = acquire_load() == ) {
... use Foo
}
Run Code Online (Sandbox Code Playgroud)
和:
auto f = new Foo();
release_store(f)
Run Code Online (Sandbox Code Playgroud)
您可以很容易地想象使用atomic with load(memory_order_acquire)和store(memory_order_release)的acquire_load和release_store的实现.但是现在如果release_store是用_mm_stream_si64实现的,这是一个非临时写入,而不是针对x64上的其他商店进行排序的?如何获得相同的语义?
我认为以下是最低要求:
atomic<Foo*> gFoo;
Foo* acquire_load() {
return gFoo.load(memory_order_relaxed);
}
void release_store(Foo* f) {
_mm_stream_si64(*(Foo**)&gFoo, f);
}
Run Code Online (Sandbox Code Playgroud)
并使用它:
// thread 1
if (f = acquire_load() == ) {
_mm_lfence();
... use Foo
}
Run Code Online (Sandbox Code Playgroud)
和:
// thread 2
auto f = new Foo();
_mm_sfence(); // ensures Foo is constructed by the time f is published to gFoo
release_store(f)
Run Code Online (Sandbox Code Playgroud)
那是对的吗?我非常肯定这里绝对需要sfence.但是那个lfence怎么样?是否需要或者简单的编译器障碍对于x64是否足够?例如asm volatile("":::"memory").根据x86内存模型,负载不会与其他负载重新排序.所以根据我的理解,只要存在编译器障碍,acquire_load()必须在if语句中的任何加载之前发生.