【问题标题】:Fast way to know compute parity of bitvector快速了解计算位向量奇偶性的方法
【发布时间】:2014-02-27 08:15:43
【问题描述】:

我正在使用 C 中的位向量。我的位向量是 unsigned long long 的。对于大量向量,我需要知道奇偶校验,即 1 的位数,是偶数还是奇数。

确切的值并不重要,重要的是奇偶校验。我想知道是否有比计算数量和检查更快的方法。我试着想点什么,但什么也找不到。

我希望它如何工作的一个简短示例:

void checkIntersection(unsigned long long int setA, unsigned long long int setB){
    if(isEven(setA & setB)){
        //do something
    }
}

【问题讨论】:

  • 搜索“bit twiddling hacks” ....

标签: c bitvector


【解决方案1】:

分而治之:

uint64_t a = value;
a ^= (a >> 32);            // Fold the 32 MSB over the 32 LSB
a ^= (a >> 16);            // reducing the problem by 50%
a ^= (a >> 8);             // <-- this can be a good break even point
..
return lookup_table[a & 0xff];  // 16 or 256 entries are typically good
..

折叠程序可以一直应用到结束:

a ^= (a >> 1);
return a & 1;

在IA中,Parity标志可以在减少到8位后直接检索。

a ^= (a &gt;&gt; 4); 提出了另一个停止除法的好点,因为某些处理器架构可以提供嵌入到 XXM(或 NEON)寄存器中的并行查找表uint8_t LUT[16]。或者只是 256 项 LUT 的潜在缓存未命中可能会简单地超过额外一轮的计算任务。在给定的架构中,最好测量哪种 LUT 大小是最佳的。

最后一张表实际上只包含 16 位,可以用序列来模拟:

return ((TRUTH_TABLE_FOR_PARITY) >> (a & 15)) & 1;

上面魔法常数的位 NParity(N) 的布尔值进行编码。

【讨论】:

    【解决方案2】:

    您可以在一个数组中预先计算一个字节中所有可能的位组合的奇偶校验:

    bool pre[256] = { 0, 1, 1, 0, 1, ....}
    

    当您需要找出更大数组的奇偶校验时,您只需这样做:

    bool parity (long long unsigned x)
    {   
        bool parity = 0;
        while(x)
        {   
            parity ^= pre[x&0xff];
            x>>=8;
        }
        return parity;
    }
    

    免责声明:我没有测试过代码,这只是一个想法。

    【讨论】:

      【解决方案3】:

      很简单。类似的东西

      unsigned population(unsigned long long x) {
        x = ((x >> 1) & 0x5555555555555555) + (x & 0x5555555555555555);
        x = ((x >> 2) & 0x3333333333333333) + (x & 0x3333333333333333);
        x = ((x >> 4) & 0x0f0f0f0f0f0f0f0f) + (x & 0x0f0f0f0f0f0f0f0f);
        x = (x >> 8) + x;  // Don't need to mask, because 64 < 0xff
        x = (x >> 16) + x;
        x = (x >> 32) + x;
        return x & 0xff;
      }
      

      应该可以。此外,一些 CPU 具有人口计数指令(我认为 x86 没有,请注意)。

      如果你喜欢这种东西,你应该看看 Henry S. Warren, Jr. 的书Hacker's Delight

      【讨论】:

      • OP 特别想要比计算位数更快的东西。
      猜你喜欢
      • 2011-05-11
      • 1970-01-01
      • 1970-01-01
      • 2022-10-06
      • 1970-01-01
      • 2017-11-14
      • 2014-02-20
      • 2018-05-29
      • 1970-01-01
      相关资源
      最近更新 更多