1
lcdtyph 217 天前 via iPhone 1
在 x86_64 架构上:
变量地址对齐的情况下,atomic read/write 确实就是一条 mov 指令 但是 atomic 包应该还会额外提供插入 mfence 来阻止指令 store-load 重排的问题 |
2
coyove 217 天前
请搜 memory order
|
3
ysc3839 217 天前 via Android
“也就是说对一个 int32 进行读写,本身即可满足第一条要求”
否的,要考虑对齐情况 |
4
PTLin 217 天前
给你补充下,go 我不太清楚,Linux 内核的原子变量的 api 还有个功能就是防止操作被编译器优化。
假设一个循环(无内存屏障,同步原语情况下)里有 a = b ,编译器有可能把这句优化到循环之外,因为编译器的角度这句话运行一次和运行多次无异,但是我们知道 b 是被多个执行流共享的变量,所以需要使用 api 防止操作被优化。 |
5
MoYi123 217 天前
内存可见性, 指令重排都不能保证
|
6
Orlion 217 天前 2
在 x86_64 上 atomic.LoadInt32 实际源码就是直接取数据,对应源码如下:
``` func Load(ptr *uint32) uint32 { return *ptr } ``` 而 WriteInt32 有所不同,其中使用了 XCHGL ,这个指令有 LOCK 指令前缀的效果,可以保证可见性。 ``` TEXT ·Store(SB), NOSPLIT, $0-12 MOVQ ptr+0(FP), BX MOVL val+8(FP), AX XCHGL AX, 0(BX) RET ``` 因此在 x86_64 平台上不使用 atomic 包也能保证原子性,但是保证不了可见性,如果程序中对可见性没有要求,以我的认知我觉得可以不使用 atomic 包,话虽如此实际工作中并发场景中该加还是加吧,说不准认知之外还有什么别的坑呢? btw ,多年前我对这个问题也有过一段时间疑问与探索,整理了一篇博客: https://blog.fanscore.cn/a/34/ 可以参考一下。 |
7
GeruzoniAnsasu 217 天前
请参考 c++ 的 memory order: https://zh.cppreference.com/w/cpp/atomic/memory_order
这堆内存序的说明可以帮助你理解为什么要有专门的原子操作函数 |
8
lance6716 217 天前 via Android
官方文档有说明,go 内存模型符合 drf-sc ,所以写程序符合 data race free 的约定就没啥问题
|