使用位集进行位图存储有什么好处?

时间:2012-09-18 01:58:01

标签: c++ stl bitmap bitset

我目前正在评估是否应该使用单个大型bitset或许多64位无符号long(uint_64)来存储大量位图信息。在这种情况下,位图表示几GB内存页面的当前状态(脏/非脏),并且有数千个条目。

我正在执行的工作要求我能够查询和更新脏页面,包括在两个脏页面位图之间执行OR操作。

要说清楚,我将执行以下操作:

  • 从文件导入位图,并使用现有位图执行按位OR运算
  • 计算汉明重量(计算设置为1的位数,表示脏页数)
  • 重置/清除一位,将其标记为已更新/清除
  • 检查位的当前状态,以确定它是否干净

看起来很容易在C ++ bitset上执行按位操作,并且很容易计算汉明重量。但是,我想这里没有任何魔力 - CPU只能在可以存储在寄存器中的字节数上执行按位操作 - 因此bitset使用的例程可能与我自己实现的相同。海明重量也可能是这样。

此外,将位图数据从文件导入到bitset看起来很难看 - 我需要多次执行位移,如here所示。我想,考虑到我将使用的位集的大小,这会对性能产生负面影响。当然,我想我可以使用许多小的位集,但这可能没有优势(其他方面可能更容易实现)。

任何建议都像往常一样受到关注。谢谢!

3 个答案:

答案 0 :(得分:1)

听起来你有一个非常具体的一次性应用程序。就我个人而言,我从来没有使用过bitset,但从我可以说它的优点是可以访问,好像它是一个bool数组,以及能够像向量一样动态增长。

从我可以收集的内容来看,你真的不需要其中任何一个。如果是这种情况,如果填充bitset是一个戏剧,我会倾向于自己做,因为分配一大堆整数并对它们进行位操作真的很简单。

鉴于具有非常具体的要求,您可能会从自己的优化中受益。访问原始位数据对此至关重要(例如,对于单个字节使用预先计算的汉明权重表,如果有备用内存,则使用两个字节)。

我一般不主张重新发明轮子......但如果你有特殊的优化要求,最好定制你的解决方案。在这种情况下,您实现的功能非常简单。

答案 1 :(得分:1)

我想如果我是你,我可能会省去任何DIY的麻烦并使用boost::dynamic_bitset。他们已经涵盖了功能方面的所有基础,包括您可以用于文件IO的流操作员重载(或者只是在unsigned int中读取数据并使用他们的转换,请参阅他们的示例)和{汉明重量的{1}}方法。 Sutter& Sons对Boost的评价极低。 Alexandrescu,他们在头文件中做了所有事情 - 没有链接,只有count相应的文件。此外,与标准库#include不同,您可以等到运行时指定bitset的大小。

编辑:Boost似乎确实允许您需要的快速输入读数。 bitset提供以下构造函数:

dynamic_bitset

底层存储是template <typename BlockInputIterator> dynamic_bitset(BlockInputIterator first, BlockInputIterator last, const Allocator& alloc = Allocator()); 的{​​{1}}(或与其几乎相同的东西),例如std::vector秒。因此,如果您将位图作为Block的{​​{1}}读入,则此构造函数会将它们直接写入内存而不进行任何位移。

答案 2 :(得分:1)

数千位听起来不是很多。但也许你有数百万。

我建议你编写你的代码 - 如果你有一个理想的实现,通过抽象(开始使用任何实现更容易编码,忽略任何性能和内存需求问题)然后尝试几个替代的特定实现来验证(通过测量它们)表现最佳。

您甚至没有考虑过的一个解决方案是使用Judy数组(特别是Judy1数组)。