给定一个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;

关于c++ - 优化从子位掩码生成父位掩码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58155201/

10-12 16:15