【发布时间】:2022-05-17 12:17:31
【问题描述】:
我需要在 2 个uint32_t 中生成uint64_t 交错位:如果A=a0a1a2...a31 和B=b0b1...b31,我需要C=a0b0a1b1...a31b31。有没有办法有效地做到这一点?到目前为止,我只有一个幼稚的方法,其中包含 32 次迭代的 for 循环,其中每次迭代都执行 C|=((A&(1<<i))<<i)|((B&(1<<i))<<(i+1))。
我想应该有一些数学技巧,例如将 A 和 B 乘以某个特殊数字,这会导致在生成的 64 位数字中将它们的位与零交错,因此剩下的就是 or 这些产品。但是我找不到这样的乘数。
另一种可能的方法是编译器内部指令或汇编指令,但我不知道。
【问题讨论】:
-
This 看起来可能有效。不确定它是否或如何扩展。
-
它应该很容易扩展;添加 16 的初始移位和
0x0000ffff0000ffff的掩码,并适当地扩展所有其他掩码。因此,新的第一步将高 16 位分割并移动到最高字的低位。 -
可以使用x86的BMI2指令集吗?两个 64 位 PDEP with opposite masks 和一个普通的按位或应该可以解决问题。 PDEP 的内在函数是
_pdep_u64() -
@PeterCordes,这是一个出色的理论解决方案,但实际上我在 Phenom 2 处理器和 CUDA 中都没有 BMI2/PDEP。
标签: c++ algorithm math assembly bit-manipulation