让v和w为两个位串。在当前的应用中,它们由8位组成。我正在寻找计算以下表达式的最快方法。
x = (v[1] & w[0]) ^ (v[2] & w[1]) ^ (v[2] & w[0]) ^ (v[3] & w[2]) ^ (v[3]) & w[1]) ^ (v[3] & w[0]) ^ ...
关于这个主题的一些想法:我注意到的一件事是这个表达式也可以写成如下。让
P(w[k]) = w[k] ^ w[k-1] ^ ... ^ w[0]
表示w的最低k + 1
位的奇偶校验。然后
x = (v[1] & P(w[0])) ^ (v[2] & P(w[1])) ^ (v[3] & P(w[2])) ^ ... ^ (v[7] & P(w[6]))
现在,如果Pw
是一个位串,其中每个位表示低位的奇偶校验,即Pw[i] = P(w[i-1])
,则x
可以写成如下:
x = P(v & Pw)
现在,在http://graphics.stanford.edu/~seander/bithacks.html上我找到了一种快速计算字符串奇偶校验的方法,但为了构建一个基于此的快速算法,我还需要一种快速的方法来计算bitstring {{1 }} 如上所述。
或许我完全以错误的方式解决这个问题,有很多奇偶校验计算要做到这一点。如果这确实是要走的路,我想知道是否有可能(假设程序将在x86上运行)在程序集中使用奇偶校验标志来加速计算。
最后,这将是我正在开发的应用程序中需要很多的计算,因此速度确实是真正的。我想知道是否可以在寄存器中进行整个计算,如果这可能比在内存中创建查找表更快。
答案 0 :(得分:5)
如果v和w真的是8位,那么你可以预先计算所有256 ^ 2组合并将结果存储在65K字节的表中。这很容易适应缓存。然后你的计算就变成:
precomputed[v<<8+w]
这是一些机器时钟和热缓存行查找。可能很难被击败。
答案 1 :(得分:3)
在x86上,自动为低8位算术运算计算奇偶校验位。基本上所需的操作简化为:
Pw = Lookup_256[w];
v &= Pw; // get the Parity as side effect on x86, or
v = Lookup_256[v] >> 7; // Reuse the table to get parity for bit 7
修改强>
通过识别部分乘积(v [i]&amp; w [j])是乘法的内部部分并且与运算符^
的串联进行整体操作,可以实现更高级别的优化和并行实现无条件(或多项式)。
整体操作将是奇偶校验(((v>&gt; 1)Px w)&amp; 0xff),其中Px表示多项式乘法,其在例如支持。 NEON和英特尔架构中的PCLMULQDQ指令。不幸的是,英特尔指令以64位字运行,这很可能,但很难将几个独立的向量v,w同时相乘。
答案 2 :(得分:0)
也许是这样的事情?
register int v, w, parity=0;
/* ... */
v >>= 1; /* Discard lsb? */
while (v) {
parity ^= v ^ w;
w = (w & 1) ^ (w >> 1);
v >>= 1;
}
parity &= 1;