位操作计算奇偶校验的最快方法是什么?

时间:2010-11-17 20:04:24

标签: c bit-manipulation parity

我的解决方案:(对于输入块的每一位,都有这样一条线)

*parity ^= (((x[0] >> 30) & 0x00000001) * 0xc3e0d69f);

所有类型都是uint32。该行取输入x的第二位,将其移至LSB并将所有其他位设置为零。然后,32位奇偶校验与该位的相应奇偶校验集进行异或。

我发现这种乘法解决方案是执行此条件XOR的最快方法。有更快的方法吗?

5 个答案:

答案 0 :(得分:4)

See here用于计算单词,字节等的奇偶校验的一些简洁的黑客

答案 1 :(得分:2)

我不完全明白你的意思是什么样的平价,但是如果这行代码是你想做的那样,它可能会有所改进。

一般规则:{0,1}中的 x x * N == - x & ; Ñ

这是因为-x表示0表示所有位都复位,1表示-1表示所有位都置位。

因此原始代码行可能会被重写为:

*parity ^= (-((x[0] >> 30) & 0x00000001) & 0xc3e0d69f);

在许多微处理器上乘以比乘法更短的时间计算了两个运算,但你应该检查一下。

此外,代码可以利用右移签名

*parity ^= (((int32_t)x[0] << 1 >> 31) & 0xc3e0d69f);

第一次移位将第30位移至第31位,即符号位,然后在所有其他位置上第二次扩展符号位,因为在大多数机器上的移位作为底板( x / 2 N ),因此用符号位(abc...yz>>3 == aaaabc...yz)填充位移位。

但是这些技巧在C标准中被称为未定义的行为,因此不可移植。小心使用它们。

答案 2 :(得分:1)

有些处理器会为您完成此操作。请参阅x86的parity flag

答案 3 :(得分:0)

如果我正确理解了这个问题,那你就是在做

for (i = 0; i < 32; i++)
    *parity ^= (((x[0] >> i) & 1) * SOME_CONST[i]); 

如果是这样,最好使用查找表:

for (i = 0; i < 4; i++)
    *parity ^= PARITY_LUT[i][ (x[0] >> (i*8)) & 0xFF];

它将花费256kb,但速度会快得多。

答案 4 :(得分:0)

奇偶校验计算任务等同于计数。也称为“计数集位”,“填充续”或简称为popcount。一些处理器具有有效的指令来进行计算(POPCNT,VCNT)。

我建议使用最低的popcount。

可以通过内联汇编器或使用内置函数来访问它: __builtin_popcount()/ __popcnt()/ std :: bitset :: count()用于GCC / VS / C ++

我个人更喜欢使用 __ builtin_parity()