我想使用boost::atomic
作为无等待环形缓冲区,如下所述:
我的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;
}
答案 0 :(得分:1)
最快的方法是将指针(unsigned char *
或指针指向包含长度的某个结构)。
当然,假设可以强制pop
采用与推送完全相同的块,这只会解决问题:现在你必须以某种方式管理这些缓冲区的分配。
用于管理块的简单示例解决方案:
unsigned char data[3096]
或其他)如果你真的不能这样做,你可以为你的块选择一个最大尺寸,并按值推送/弹出那个尺寸的对象......但老实说这看起来非常浪费(即使对象知道它的长度,因此对于较小的块,不需要memcpy
整个3k数组。)