2

当我阅读有关示例无等待环形缓冲区实现的 boost atomics 时:

https://www.boost.org/doc/libs/1_66_0/doc/html/atomic/usage_examples.html#boost_atomic.usage_examples.example_ringbuffer

我想知道 memory_order_acquire 是否需要

if (next_head == tail_.load(boost::memory_order_acquire))

似乎 memory_order_relaxed 也应该起作用。我的论点是

 value = ring_[tail];

发生之前

tail_.store(next(tail), boost::memory_order_release)

在 pop() 调用中。所以我们确定在我们存储 push() 调用之前已经读取了数据

 ring_[head] = value;

我在下面粘贴了整个 boost 示例代码以便于参考。谢谢!

#include <boost/atomic.hpp>

 template<typename T, size_t Size>
 class ringbuffer {
 public:
 ringbuffer() : head_(0), tail_(0) {}

 bool push(const T & value)
 {
    size_t head = head_.load(boost::memory_order_relaxed);
    size_t next_head = next(head);
    if (next_head == tail_.load(boost::memory_order_acquire))

//上面的tail_.load可以使用boost::memory_order_relaxed吗?

    return false;
    ring_[head] = value;
    head_.store(next_head, boost::memory_order_release);
    return true;
 }
 bool pop(T & value)
{
    size_t tail = tail_.load(boost::memory_order_relaxed);
    if (tail == head_.load(boost::memory_order_acquire))
    return false;
   value = ring_[tail];
   tail_.store(next(tail), boost::memory_order_release);
   return true;
 }
 private:
   size_t next(size_t current)
   {
      return (current + 1) % Size;
   }
  T ring_[Size];
  boost::atomic<size_t> head_, tail_;

};

4

2 回答 2

1

一个原因是按顺序:

if(next_head == tail_.load(boost::memory_order_acquire))
    return false;
ring_[head] = value; // A non-atomic store.

memory_order_acquire确保以下非原子存储不会被重新排序以先于tail_.

memory_order_relaxed,另一方面,不会阻止重新排序,因此在这里是不够的。

(假设boost::memory_order等价于std::memory_order。)


发布-获取订购

在强排序系统(x86、SPARC TSO、IBM 大型机等)上,对于大多数操作来说,发布-获取排序是自动的。此同步模式不会发出额外的 CPU 指令;只有某些编译器优化会受到影响(例如,禁止编译器将非原子存储移动到原子存储释放之后或在原子加载获取之前执行非原子加载)。在弱序系统(ARM、Itanium、PowerPC)上,使用特殊的 CPU 负载或内存栅栏指令。

于 2018-07-11T14:58:18.100 回答
0

据我所知,tail_.load(boost::memory_order_acquire)inpush()head_.load(boost::memory_order_acquire)inpop()都可以放松并替换为 xx.load(boost::memory_order_relaxed).

于 2018-12-04T15:02:05.300 回答