清除boost::dynamic_bitset中每k位的最快方法

Fastest way to clear every kth bit in boost::dynamic_bitset

本文关键字:方法 中每 boost dynamic bitset 清除      更新时间:2023-10-16

从偏移量j中清除boost::dynamic_bitset中每个kth位的最快方法是什么?

目前我正在做这个,这是相当缓慢的(伪代码):

for (i = j; i < bitset.size(); i += k) {
    bitset[i] = 0;
}

必须完成数百万位清除,所以这就是为什么我在寻找一种快速的方法来完成它。

好的,不确定这是否更快,但我认为你可以测试:

关键操作是掩码位集的构造,您应该有一个预构造掩码的表(这将允许您将每个k第th位重置为每32位[在我的平台上unsigned long是32位])。然后,昂贵的操作是构造一个与输入相同大小的完整掩码——如果它总是相同的大小,并且内存不受限制,您可以简单地为它构造一个查找表,然后简单地将两个位集&

#include <iostream>
#include <limits>
#include <boost/dynamic_bitset.hpp>
using namespace std;
int main(void)
{
  boost::dynamic_bitset<> orig(64);
  for (int i = 0; i < orig.size(); ++i) {
    orig[i] = rand() % 2;
  }
  std::cout << orig << std::endl;
  unsigned long mask = 0x88888888; // reset every 4th bit
  boost::dynamic_bitset<> mbits(numeric_limits<unsigned long>::digits, mask);
  while(mbits.size() < orig.size())
    mbits.append(mask);
  mbits.resize(orig.size()); // incase not aligned
  mbits <<= 5; // arbitary starting point (i.e. j)
  std::cout << mbits << std::endl;
  mbits.flip();
  std::cout << mbits << std::endl;
  orig &= mbits;
  std::cout << orig << std::endl;
  return 0;
}

更新:好吧,只是非常粗略地测试了一下,你可以在这里看到结果:http://www.ideone.com/ez3Oc,使用预构建的掩码,它可以快近40%…

对于非常大的位集,计算一个n位长的掩码(其中n是您的本地大小,例如x86_64为64),如Nim建议,应用它。
如果您的本地长度不是k的倍数,则相应地移动它。
因此,如果你的原生长度是10,并且想要设置一个30位长的bitset的每3位,你需要像这样传递3次:
前10位:0010010010
秒10位:0100100100
最后10位:1001001001
因此,在应用每个掩码后,你需要将它向左移动(n%k)位。