去原子和记忆顺序

时间:2015-03-08 07:29:12

标签: c++11 go atomic lock-free

我正在从c ++ 11移植一个无锁队列,我遇到了诸如

之类的东西
auto currentRead = writeIndex.load(std::memory_order_relaxed);

在某些情况下std::memory_order_releasestd::memory_order_aqcuire c11中上述的等价物也类似于

unsigned long currentRead = atomic_load_explicit(&q->writeIndex,memory_order_relaxed);

这些的含义描述为here

是否有相当于这样的东西,或者我只是使用像

这样的东西
var currentRead uint64 = atomic.LoadUint64(&q.writeIndex)
在移植基准测试并且仅使用LoadUint64之后,它似乎按预期工作但数量级更慢,我想知道这些专业操作对性能有多大影响。

  • 我附加链接的更多信息
  

memory_order_relaxed :放松操作:没有同步   或排序约束,此操作只需要原子性。

     

memory_order_consume :执行具有此内存顺序的加载操作   受影响的内存位置上的使用操作:没有读取   当前线程依赖于当前加载的值即可   在此负载之前重新排序。这可确保写入数据相关   释放相同原子变量的其他线程中的变量是   在当前线程中可见。在大多数平台上,这会影响   仅限编译器优化。

     

memory_order_acquire :具有此内存顺序的加载操作会对受影响的内存位置执行获取操作:否   在此之前可以重新排序当前线程中的内存访问   加载。这可以确保释放其他线程的所有写入   在当前线程中可以看到相同的原子变量。

     

memory_order_release :具有此内存顺序的存储操作执行释放操作:当前没有内存访问   线程可以在这个商店之后重新排序。这确保了所有写入   在当前线程中,在获取或获取的其他线程中可见   相同的原子变量和带有依赖关系的写入   原子变量在消耗相同的其他线程中变得可见   原子。

1 个答案:

答案 0 :(得分:7)

您需要阅读The Go Memory Model

您会发现Go与C ++中的控件完全不同 - 您的帖子中没有C ++功能的直接翻译。这是Go作者的深思熟虑的设计决定 - 围棋座右铭是Do not communicate by sharing memory; instead, share memory by communicating

假设标准go频道不足以满足您的需求,每个内存访问都有2个选择,使用sync/atomic中的功能,以及是否需要使用它们与否取决于仔细阅读Go Memory Model并分析您只能执行的代码。