【问题标题】:Circular buffer optimizations循环缓冲区优化
【发布时间】:2014-04-05 09:47:58
【问题描述】:

我有一个大小为 2 的循环缓冲区。我的目标是优化它的工作。这是简短的代码:

class CircularBuffer
{
public:
  CircularBuffer(unsigned int bufferSize); // align this size to power of 2
  void read(char * dst, unsigned int bytes);
  void write(char * src, unsigned int bytes);
private:
  unsigned int m_readOffset;
  unsigned int m_writeOffset;
  std::vector<char> m_buffer;
};

CircularBuffer::write(char * src, unsigned int bytes)
{
  int dif = bytes - (m_buffer.size() - m_writeOffset);
  unsigned int mask = ~(dif >> 31); // 0 or 0xFFFFFFFF
  dif &= mask; // now i know how much bytes i need to put at the beginning of the buffer
  memcpy(&m_buffer[m_writeOffset], src, bytes - dif);
  memcpy(&m_buffer[0], src + bytes - dif, dif);
  m_writeOffset = (m_wirteffset + bytes) & (m_buffer.size() -1);
}

m_writeOffset 表示已放入缓冲区的字节数。 如您所见,我摆脱了 if (remain size in buff

但是我的首席程序员告诉我,有一种方法可以使用按位运算来计算要在缓冲区末尾放置多少字节以及在开头放置多少字节,因为缓冲区的大小是 2 的幂。有什么建议吗?

【问题讨论】:

  • 你为什么不问问告诉你有办法的人?
  • 请注意低级技巧!= 高效代码。尝试使用标准库循环缓冲区 (std::deque) 并对其进行分析。
  • 低级技巧 = 难以阅读且漏洞百出。看来您的首席程序员“聪明”但不聪明。 “聪明”的程序员只会惹麻烦。你看,如果你试图通过与我的代码审查来获得你的 ::write 方法,我会要求你在 C++ 标准中查找右移负整数的结果是什么以及它到底在哪里说符号重复。然后你会被卡住,因为你找不到这些信息,因为它不存在。负整数右移是实现定义的,不可移植。
  • gnasher729,那你觉得我应该怎么做?如果您很难阅读此内容,也许您很难理解那里发生了什么?如果将此函数用于多线程高度可执行的代码块,我们确实可以看到“良好可读”代码和“良好实现”代码之间的性能差异。我完全同意右移实现,因此我们可以信任编译器文档。有没有人会尝试寻找技术决策而不是提供如何编程的建议?
  • Manu343726,std::deque 是对象的容器,它不是内存 fifo。如您所见,我使用 std::vector 作为堆内存的智能指针。就这样。你认为如何使用 std::deque?插入 - 删除在每次调用时重新分配内存的操作?我在这里看不到有效的代码。

标签: c++ bit-manipulation circular-buffer


【解决方案1】:

您已经在使用无符号变量来跟踪队列的前后(这很好);只需在每次写入(入队)操作时增加 m_writeOffset 并在每次读取(出队)操作时增加 m_readOffset。计算缓冲区元素的剩余量很简单:

// returns the distance between m_readOffset and m_writeOffset
// (the count of the actual buffer elements):
uint32_t CircularBuffer::Size()
{
    if (m_readOffset < m_writeOffset)
    {
        return (m_writeOffset - m_readOffset);
    }
    else
    {
        return (m_readOffset - m_writeOffset);
    }
} 

查看我的基于 2 循环队列的 STL 模板实现的源代码:

CircularQueue.h

CircularQueue.cpp

【讨论】:

    猜你喜欢
    • 2020-03-19
    • 1970-01-01
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多