Boost atomic:具有大量数据的无等待环形缓冲区

时间:2013-05-31 16:51:43

标签: c++ boost atomic circular-buffer

我想使用boost::atomic作为无等待环形缓冲区,如下所述:

Boost Example

我的producer同时提供大量数据(unsigned char,+ - 3000个值),就像一个逐行填充的矩阵一样。在缓冲区中push这些值的最佳方法是什么?我应该只是循环它们还是我可以memcpy以某种方式进入它们?

如果我想同时读取一堆值,pop也一样......


这是我想出的,这不应该是什么原因? 我只需要确保RINGBUFFERSIZE % iSize = 0

#define RINGBUFFERSIZE = 30000

ring_[RINGBUFFERSIZE];

bool push(unsigned char* iData, int iSize)
{
    size_t head = head_.load(boost::memory_order_relaxed);
    size_t next_head = next(head,iSize);
    if (next_head == tail_.load(boost::memory_order_acquire))
    return false;
    memcpy(ring_+head,iData,iSize);
    head_.store(next_head, boost::memory_order_release);
}

bool pop(unsigned char * value, int iSize)
{
     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,iSize), boost::memory_order_release);
     return true;
}


size_t next(size_t current, int iSize)
{
     return (current + iSize) % RINGBUFFERSIZE;
}

1 个答案:

答案 0 :(得分:1)

最快的方法是将指针(unsigned char *或指针指向包含长度的某个结构)。

当然,假设可以强制pop采用与推送完全相同的块,这只会解决问题:现在你必须以某种方式管理这些缓冲区的分配。


用于管理块的简单示例解决方案:

  1. 预分配“足够多”固定大小的块对象(比如动态长度+ unsigned char data[3096]或其他)
  2. 在等待无效环缓冲区中发送块的地址
  3. 当消费者完成后,在另一个环形缓冲区中发送地址返回,这样生产者就可以回收相同的块对象

  4. 如果你真的不能这样做,你可以为你的块选择一个最大尺寸,并按值推送/弹出那个尺寸的对象......但老实说这看起来非常浪费(即使对象知道它的长度,因此对于较小的块,不需要memcpy整个3k数组。)