相关疑难解决方法(0)

在x64上使用非临时存储获取/释放语义

我有类似的东西:

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语句中的任何加载之前发生.

c++ multithreading x86-64 lock-free stdatomic

18
推荐指数
1
解决办法
1267
查看次数

标签 统计

c++ ×1

lock-free ×1

multithreading ×1

stdatomic ×1

x86-64 ×1