1

我想使用boost::atomic此处描述的无等待环形缓冲区:

提升示例

Myproducer同时提供大量数据(无符号字符,+- 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;
}
4

1 回答 1

1

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

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


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

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

如果你真的不能这样做,你可以为你的块选择一个最大大小并按值推送/弹出该大小的对象......但老实说,这似乎非常浪费(即使对象知道它的长度,所以不必memcpy整个 3k 数组用于较小的块)。

于 2013-05-31T16:56:42.213 回答