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

C 位运算计算奇偶校验的最快方法是什么?,c,bit-manipulation,parity,C,Bit Manipulation,Parity,我的解决方案:(对于输入块的每一位,都有这样一条线) 所有类型均为uint32。该行获取输入x的第二位,将其移动到LSB,并将所有其他位设置为零。然后,32位奇偶校验与该位对应的奇偶校验集异或 我发现这个乘法解是实现条件异或的最快方法。有没有更快的方法?对于一些计算单词、字节等奇偶校验的简单方法,有些处理器会帮你做到这一点。请参阅x86。我不完全理解您所指的奇偶校验类型,但如果这行代码符合您的要求,则可能会有所改进 一般规则:对于{0,1}x*N==-x&N中的x 这是因为0的-x是所有位的重置

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

所有类型均为uint32。该行获取输入x的第二位,将其移动到LSB,并将所有其他位设置为零。然后,32位奇偶校验与该位对应的奇偶校验集异或


我发现这个乘法解是实现条件异或的最快方法。有没有更快的方法?

对于一些计算单词、字节等奇偶校验的简单方法,有些处理器会帮你做到这一点。请参阅x86。

我不完全理解您所指的奇偶校验类型,但如果这行代码符合您的要求,则可能会有所改进

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

这是因为0的-x是所有位的重置,而1的-1是所有位的重置

因此,原始代码行可以重写为:

*parity ^= (-((x[0] >> 30) & 0x00000001) & 0xc3e0d69f);
在许多微处理器上,哪两个运算的计算时间比乘法要短,但您应该检查一下

代码还可以利用有符号的向右移位

*parity ^= (((int32_t)x[0] << 1 >> 31) & 0xc3e0d69f);
*奇偶校验^=((int32_t)x[0]>31)和0xc3e0d69f);
第一次移位将第30位移到第31位,即符号位,然后在所有其他机器上进行第二次扩展符号位,因为在大多数机器上右移充当地板(x/2N),因此用符号位填充移位后的位(
abc…yz>>3==aaaaabc…yz


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

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

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

*奇偶校验^=((x[0]>>i)和1)*一些常数[i]);
如果是这样,最好使用查找表:

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

*奇偶校验^=奇偶校验LUT[i][(x[0]>>(i*8))&0xFF];

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

奇偶校验计算任务相当于一个一个的计数。它也被称为“计数设置位”、“人口控制”或简单的popcount。一些处理器有高效的指令来计算它(POPCNT、VCNT)

我建议使用popcount的最低位

它可以通过内联汇编程序或使用内置程序访问: __GCC/VS/C的内置\u popcount()/\u popcnt()/std::bitset::count()++


就我个人而言,我更喜欢通过使用\u内置奇偶校验()

将这项工作交给编译器。你在说什么语言/处理器?你试图计算奇偶校验的块有多大?WAT:乘以0xC3E0D69F的点?我在谈论C++。数据块是256位(因此uint32 x[0..7]。奇偶校验是32位(存储在uint32中)。对于输入的每一个设置位,都会对奇偶校验字段应用一个特定的异或掩码(LFSR的并行实现)。它不仅仅是偶数/奇数奇偶校验,它有32位。谢谢-我已经尝试了页面上的提示。尤其是“无分支的条件设置或清除位”比乘法解慢。听起来不错-非常感谢,我明天会试试!
for (i = 0; i < 4; i++)
    *parity ^= PARITY_LUT[i][ (x[0] >> (i*8)) & 0xFF];