C++ Boost atomic:具有大量数据的无等待环形缓冲区
我想使用C++ Boost atomic:具有大量数据的无等待环形缓冲区,c++,boost,atomic,circular-buffer,C++,Boost,Atomic,Circular Buffer,我想使用boost::atomic作为无等待环形缓冲区,如下所述: 我的producer同时提供大量数据(无符号字符,+-3000个值),就像一个矩阵一样,它会逐行填充。将这些值推送到缓冲区的最佳方法是什么?我应该在它们上面循环还是可以在它们内部循环 如果我想同时读取一组值,pop也是如此 这就是我想到的,有什么理由不好吗? 我只需要确保RINGBUFFERSIZE%iSize=0 #define RINGBUFFERSIZE = 30000 ring_[RINGBUFFERSIZE];
boost::atomic
作为无等待环形缓冲区,如下所述:
我的producer
同时提供大量数据(无符号字符,+-3000个值),就像一个矩阵一样,它会逐行填充。将这些值推送到缓冲区的最佳方法是什么?我应该在它们上面循环还是可以在它们内部循环
如果我想同时读取一组值,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;
}
最快的方法是将指针(无论是
无符号字符*
还是指向包含长度的某个结构的指针)推入
当然,假设可以强制pop
获取与推送的数据块完全相同的数据块,这就解决了问题:现在您必须以某种方式管理这些缓冲区的分配
管理区块的简单示例解决方案:
无符号字符数据[3096]
或其他)如果你真的不能做到这一点,你可以为你的块选择一个最大大小,并按值推/弹出该大小的对象。。。但老实说,这似乎非常浪费(即使对象知道它的长度,所以不必
memcpy
整个3k数组来获得较小的块)。最快的方法是推送一个指针(或者无符号字符*
或者指向包含长度的某个结构的指针)
当然,假设可以强制pop
获取与推送的数据块完全相同的数据块,这就解决了问题:现在您必须以某种方式管理这些缓冲区的分配
管理区块的简单示例解决方案:
无符号字符数据[3096]
或其他)如果你真的不能做到这一点,你可以为你的块选择一个最大大小,并按值推/弹出该大小的对象。。。但老实说,这似乎非常浪费(即使对象知道它的长度,所以不必
memcpy
整个3k数组来存储较小的块)。确切地说,指向的内存将不再有效,所以我需要复制数据本身。当然,您可以控制缓冲区的有效性吗?数据来自tcp连接,所以每次读取我都需要存储它。是的,但是你读取到的内存的分配和生命周期管理是在你的控制之下。。。除非您特别关注重新组装部分读取?您当然可以这样做,但我认为使用这个容器(它面向离散值对象,而不是可变长度数据流)并不容易。确切地说,指向的内存将不再有效,所以我需要复制数据本身。当然你可以控制缓冲区的有效性吗?数据来自tcp连接,所以每次读取时我都需要存储数据。是的,但是你读取到的内存的分配和生命周期管理由你控制。。。除非您特别关注的是重新组装部分读取?您当然可以这样做,但我认为使用这个容器(面向离散值对象而不是可变长度数据流)并不容易。建议的解决方案不太有效,因为next\u head
可能已经结束。在这种情况下,您没有一个连续的块,也不能执行单个memcpy
(当然,您可以检查这种情况,也可以执行两个)。建议的解决方案不太有效,因为next\u head
可能已经结束。在这种情况下,您没有一个连续的块,无法执行单个memcpy
(当然,您可以检查这种情况,也可以执行两个)。