2位集之间的快速汉明距离

Fast hamming distance between 2 bitset

本文关键字:汉明距离 之间 2位      更新时间:2023-10-16

我正在编写一个严重依赖于(1)访问单个位和(2)2位集a和B之间的汉明距离计算的软件(即。比特集非常大,在10K到1M比特之间,我有一堆比特集。由于在编译时不可能知道bitset的大小,所以我使用vector < bool >,但我计划很快迁移到boost::dynamic_bitset

以下是我的问题:

(1)有关于哪些实现具有最快的单比特访问时间的想法吗?

(2)要计算汉明距离,最简单的方法是遍历单个比特并计算两个比特集之间的差异。但是,我的感觉是,在字节而不是位之间循环可能要快得多,执行R = byteA XOR byteB,并在包含255个条目的表中查看与R相关的"本地"距离。另一种解决方案是存储255 x 255矩阵并直接访问byteA和byteB之间的距离,而无需操作。所以我的问题:任何想法如何实现从std::vector < bool >或boost::dynamic_bitset?换句话说,你知道是否有一种方法可以访问字节数组,或者我必须从头开始重新编码一切?

(1)可能是vector<char>(甚至是vector<int>),但这在典型硬件上至少浪费7/8的空间。如果您使用一个字节或更多字节来存储它们,则不需要解包。我不知道vector<bool>dynamic_bitset哪个更快。这可能取决于c++的实现。

(2) boost::dynamic_bitset具有operator^count成员,这两个成员可以一起用来计算汉明距离,这可能是一种快速但浪费内存的方式。您还可以使用to_block_range访问底层缓冲区;要使用它,您需要实现一个汉明距离计算器作为OutputIterator

如果您从头开始编写代码,您可能会做得比每次一个字节更好:每次从每个bitset中获取一个单词。XOR的成本应该非常低,然后使用特定于实现的内置popcount,或者使用您可以找到的最快的位处理popcount(可能涉及也可能不涉及256项查找)。

[编辑:看起来这可能适用于boost::dynamic_bitset::to_block_range, Block被选为intlong。]遗憾的是,它向OutputIterator写入数据,而不是向您提供InputIterator——我无法立即看到如何使用它来一起迭代两个bitset,除非使用额外的线程或首先将其中一个bitset复制到int数组中。无论哪种方式,您都将承担一些复制开销,如果将程序控制权留给您,这些开销本可以避免。对于这个任务,线程是相当复杂的,当然有它自己的开销,并且复制数据可能并不比使用operator^count()好。

我知道这会被认为是异端邪说,但这里是:你可以使用&vector[0];(对于向量ymmv)然后,你可以使用c风格的函数对它进行迭代;也就是说,将指针转换为int指针或类似的大指针,执行如上所述的汉明算法,并每次移动一个字长的指针。这只会起作用,因为您知道这些位是连续地打包在一起的,并且容易受到攻击(例如,如果向量被修改,它可能会移动内存位置)。