c++ - golangatomic.Load 有获取语义吗?

标签 c++ go

给定一个 C++ 代码片段:

int a = 0;
atomic<int> b{0};

Thread 1                         
a = 1;
b.store(1,memory_order_release);

Thread 2
while(!b.load(memory_order_acquire)); 
assert(a==1);

我们知道断言永远不会触发。

另一方面,golang atomic.Store使用隐含内存屏障的 xchg 指令,因此它可以产生与 c++11 一样的 memory_order_release 语义。

//go:noescape
func Store(ptr *uint32, val uint32)
TEXT runtime∕internal∕atomic·Store(SB), NOSPLIT, $0-12
    MOVQ    ptr+0(FP), BX
    MOVL    val+8(FP), AX
    XCHGL   AX, 0(BX)
    RET

但是,执行atomic.Load是纯go代码,这意味着汇编时只需mov指令。

//go:nosplit
//go:noinline
func Load(ptr *uint32) uint32 {
    return *ptr
}

那么,golangatomic.Load有获取语义吗?
如果它是如何工作的,如果不是,如何确保内存排序或使 a=1 可见?

最佳答案

在 x86/amd64 等强有序架构上,获取加载和释放存储只是常规加载和存储。为了使它们原子化,您需要确保内存与操作数大小对齐(Go 中自动对齐),并且编译器不会以不兼容的方式对它们重新排序,或者优化它们(例如,重用寄存器中的值)从内存中读取它。)

Go 原子 Load* 和 Store* 函数是顺序一致的。这是一种更强大的内存排序形式,即使在 x86/amd64 上也需要内存栅栏(或具有隐式内存栅栏的指令)。

引用rsc:

Go's atomics guarantee sequential consistency among the atomic variables (behave like C/C++'s seqconst atomics), and that you shouldn't mix atomic and non-atomic accesses for a given memory word.

关于c++ - golangatomic.Load 有获取语义吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55787091/

相关文章:

c++ - 文本文件 C++ 编辑第一行

c++ - NVCC 和 NVRTC 在编译为 PTX 时的区别

go - 在 Go 中,如何自动将循环索引强制转换为 uint?

Golang 模板 : what is in the context?

go - 检查函数是否作为 goroutine 被调用

c++ - 我应该为 C++/CMake 项目使用 MinGW 来最小化 MS 的 DLL 的依赖性吗?

c++ - 不确定如何使用 enable_if 及其重要性

c++ - 如果RMW操作没有任何变化,是否可以针对所有内存顺序对其进行优化?

go - 如何在 HTML 模板中不转义

concurrency - 这个chan是怎么泄露的?