2014-04-05 142 views
2

我有一个大小为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(保持大小在buff < srcSize)等条件,并使用位掩码计算writeOffset。

但我的领导程序员告诉我,有一种方法可以计算放置在缓冲区末尾的多少个字节以及使用按位操作时要放置多少个字节,因为缓冲区的大小是2的幂。任何建议?

+2

你为什么不问那个告诉你有什么方法的人? –

+0

请注意,低级别技巧!=高效代码。试试标准库循环缓冲区(['std :: deque'](http://en.cppreference.com/w/cpp/container/deque))并对其进行配置。 – Manu343726

+2

低级技巧=难以阅读并且充满了错误。看起来你的主要程序员是“聪明”,但不聪明。 “聪明”的程序员只会造成麻烦。你看,如果你试图通过代码审查得到你的::写入方法,我会要求你在C++标准中查找右移一个负整数的结果是什么,以及它究竟在哪里表示标志是重复的。然后你会被卡住,因为你不会找到这些信息,因为它不在那里。右移一个负整数是实现定义的,而不是可移植的。 – gnasher729

回答

0

您已经在使用无符号变量来跟踪队列的正面和背面(这很好);在每次读(排队)操作时简单地增加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); 
    } 
} 

查阅的源代码到我的STL模板实现一个基数为2的循环队列的:

CircularQueue.h

CircularQueue.cpp