为了账号安全,请及时绑定邮箱和手机立即绑定

转到原子和内存顺序

转到原子和内存顺序

Go
噜噜哒 2021-09-20 14:53:14
我正在从 c++11 移植一个无锁队列,我遇到了诸如auto currentRead = writeIndex.load(std::memory_order_relaxed);在某些情况下std::memory_order_release,并std::memory_order_aqcuire 也为C11以上的equivelent是一样的东西unsigned long currentRead = atomic_load_explicit(&q->writeIndex,memory_order_relaxed);此处描述了这些的含义在 go 中是否有类似的东西,或者我只是使用类似的东西var currentRead uint64 = atomic.LoadUint64(&q.writeIndex)移植后我进行了基准测试并仅使用 LoadUint64 它似乎按预期工作,但速度慢了几个数量级,我想知道这些专门的操作对性能有多大影响。我附加的链接中的更多信息memory_order_relaxed :Relaxed 操作:没有同步或排序约束,这个操作只需要原子性。memory_order_consume:具有此内存顺序的加载操作对受影响的内存位置执行消耗操作:在此加载之前,可以重新排序依赖于当前加载的值的当前线程中的任何读取。这确保了对释放相同原子变量的其他线程中的数据相关变量的写入在当前线程中可见。在大多数平台上,这仅影响编译器优化。memory_order_acquire:具有此内存顺序的加载操作对受影响的内存位置执行获取操作:在此加载之前,当前线程中的内存访问不能重新排序。这确保了释放相同原子变量的其他线程中的所有写入在当前线程中都是可见的。memory_order_release:具有此内存顺序的存储操作执行释放操作:在此存储之后,当前线程中的任何内存访问都不能重新排序。这确保了当前线程中的所有写入在获取相同原子变量的其他线程中都是可见的,并且携带对原子变量的依赖的写入在消耗相同原子的其他线程中变得可见。
查看完整描述

1 回答

?
喵喔喔

TA贡献1735条经验 获得超5个赞

你需要阅读Go Memory Model

您会发现 Go 与您在 C++ 中拥有的控件完全不同——您的帖子中没有直接翻译 C++ 功能。这是 Go 作者的一个深思熟虑的设计决定——Go 的座右铭是不要通过共享内存进行通信;相反,通过通信共享内存。

假设标准 go 通道不足以满足您的需求,您将有 2 个选择用于每次内存访问,使用同步/原子设施,以及您是否需要使用它们将取决于仔细阅读 Go Memory Model 并分析您的代码,这只有您才能做到。


查看完整回答
反对 回复 2021-09-20
  • 1 回答
  • 0 关注
  • 201 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信