AVX2向量中每个元素的前导零位计数

问题描述 投票:1回答:2

[使用AVX512,有一个固有的_mm256_lzcnt_epi32,它返回一个矢量,对于8个32位元素中的每一个,它都包含输入矢量元素中前导零位的数量。

是否有一种仅使用AVX和AVX2指令来实现此目标的有效方法?

当前,我正在使用一个提取每个元素并应用_lzcnt_u32函数的循环。

bit-manipulation simd avx avx2 avx512
2个回答
2
投票
然后抓住double的指数位并消除偏差。

我认为整数log2与lzcnt相同,但是在2的幂处可能存在1比1的偏移。

[Standford Graphics比特黑客页面列出了您可以使用的其他无分支比特黑客,它们可能仍然比8倍标量lzcnt好。

[如果您知道自己的数字始终很小(例如小于2 ^ 23),则可以使用float执行此操作,并避免拆分和混合。

int v; // 32-bit integer to find the log base 2 of int r; // result of log_2(v) goes here union { unsigned int u[2]; double d; } t; // temp t.u[__FLOAT_WORD_ORDER==LITTLE_ENDIAN] = 0x43300000; t.u[__FLOAT_WORD_ORDER!=LITTLE_ENDIAN] = v; t.d -= 4503599627370496.0; r = (t.u[__FLOAT_WORD_ORDER==LITTLE_ENDIAN] >> 20) - 0x3FF; ``` The code above loads a 64-bit (IEEE-754 floating-point) double with a 32-bit integer (with no paddding bits) by storing the integer in the mantissa while the exponent is set to 252. From this newly minted double, 252 (expressed as a double) is subtracted, which sets the resulting exponent to the log base 2 of the input value, v. All that is left is shifting the exponent bits into position (20 bits right) and subtracting the bias, 0x3FF (which is 1023 decimal).

[[要使用AVX2进行此操作,将set1_epi32(0x43300000)_mm256_castps_pd混合并移位和混合奇/偶半数以获得__m256d。减去后,_mm256_castpd_si256并移位/混合低/将两半放到适当的位置,然后遮盖以得到指数。
使用AVX2对FP位模式进行整数运算非常有效,在FP数学指令的输出上进行整数移位时,旁路延迟只有1个周期的额外延迟。

((待办事项:使用C ++内在函数编写,编辑欢迎内容,否则其他人可以将其作为答案。)

我不确定您是否可以使用int->double

conversion

进行任何操作,然后读取指数字段。负数没有前导零,而正数给出的指数取决于幅度。
[如果您确实希望这样做,您将一次走一个128位通道,改组以馈送xmm-> ymm包装的int32_t->包装的double转换。
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.