必须有一个非常快速的方法来计算这个按位表达式?

时间:2013-11-13 13:27:24

标签: c++ algorithm assembly binary x86

让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上运行)在程序集中使用奇偶校验标志来加速计算。

最后,这将是我正在开发的应用程序中需要很多的计算,因此速度确实是真正的。我想知道是否可以在寄存器中进行整个计算,如果这可能比在内存中创建查找表更快。

3 个答案:

答案 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;