优化从子位掩码生成父位掩码

罗宾·马库斯

给定一个 64 位子掩码输入,例如:

10000000 01000000 00100000 00010000 00001000 00000100 00000010 00000000

8 位父掩码将是:

11111110

父掩码中的单个位映射到子掩码字符串中的 8 位,当 8 个子位之一设置为 1 时,父掩码中的位设置为 1。计算此值的简单算法如下:

unsigned __int64 childMask = 0x8040201008040200; // The number above in hex
unsigned __int8 parentMask = 0;
for (int i = 0; i < 8; i++)
{
    const unsigned __int8 child = childMask >> (8 * i);
    parentMask |= (child > 0) << i;
}

我想知道上面的代码是否还有任何优化要做。代码将在 CUDA 上运行,我希望尽可能避免分支。对于答案,C++/C 中的代码会很好。for 循环可以展开,但我宁愿将其留给编译器进行优化,并在必要时使用例如#pragma unroll.

哈罗德

一种可能的方法是使用__vcmpgtu4逐字节比较,将结果作为打包掩码返回,可以与 0x08040201(高半部分为 0x80402010)进行 AND 运算,将它们转换为最终结果的位,但随后它们需要水平求和,这似乎没有得到很好的支持,但可以使用普通的旧 C 样式代码来完成。

例如,

unsigned int low = childMask;
unsigned int high = childMask >> 32;
unsigned int lowmask = __vcmpgtu4(low, 0) & 0x08040201;
unsigned int highmask = __vcmpgtu4(high, 0) & 0x80402010;
unsigned int mask = lowmask | highmask;
mask |= mask >> 16;
mask |= mask >> 8;
parentMask = mask & 0xff;

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章