2011-04-25 54 views
3

我正在写一个帮助类,我打算用于从数据块反向读取位。阅读位性能

我试图做一个优化,我用“rol”指令来掩盖数据。但是,令我惊讶的是,这实际上比每次访问期间创建新的位掩码要慢。

class reverse_bit_reader 
{ 
public: 
    static const size_t bits_per_block = sizeof(unsigned long)*8; 
    static const size_t high_bit = 1 << (bits_per_block-1); 

    reverse_bit_reader(const void* data, size_t size) 
     : data_(reinterpret_cast<const unsigned long*>(data)) 
     , index_(size-1) 
    { 
      // Bits are stored in left to right order, potentially ignore the last bits 
     size_t last_bit_index = index_ % bits_per_block; 
     bit_mask_ = high_bit >> (last_bit_index+1); 
     if(bit_mask_ == 0) 
      bit_mask_ = high_bit; 
    } 

    bool next_bit1() 
    { 
     return get_bit(index_--); 
    } 

    bool next_bit2() // Why is next_bit1 faster? 
    { 
     __asm // Rotate bit_mask. 
     { 
      mov eax, [ecx+0]; 
      rol eax, 1; 
      mov [ecx+0], eax; 
     } 
     return data_[index_--/bits_per_block] & bit_mask_;  
    } 

    bool eof() const{return index_ < 0;} 
private: 

    bool get_bit(size_t index) const 
    {  
     const size_t block_index = index/bits_per_block; 
     const size_t bit_index = index % bits_per_block; 
     const size_t bit_mask = high_bit >> bit_index; 
     return data_[block_index] & bit_mask; 
    } 

    unsigned long bit_mask_; 
    int index_; 
    const unsigned long* data_; 
}; 

任何人都可以解释为什么next_bit1比next_bit2更快吗?

+2

其他的解决方法:为什么它应该更快?您正在加载蒙片,旋转一圈,然后再次储存。这应该比将寄存器设置为1并将其移动一个从'index%bits_per_block'计算出来的值慢一些,然后无论如何将其转换为简单的“和”指令。如果您想确切知道发生了什么,请研究生成的目标代码。 – hirschhornsalz 2011-04-25 14:13:20

+11

因为编译器比生成好代码好。相信它。 – ybungalobill 2011-04-25 14:19:06

+0

'1 <<(bits_per_block-1)'行包含错误。在我的电脑上它产生了零,编译器警告我。考虑改变'1UL'。 – Cubbi 2011-04-25 15:25:51

回答

1

如果你打算从最重要的位开始按顺序读取位,并且希望它尽可能快,那么你可以沿着这些方向行吗?

#define GETBIT ((theBit = (theLong < 0)), (theLong <<= 1), theBit)