使用gcc生成BZHI指令

4

我正在尝试让 gcc 生成 BMI2 的 bzhi 指令,而不使用内置函数,以创建可移植的代码。

鉴于 bzhi 的结果,我希望这个目标相对容易实现。以下 SO 回答 提供了一个简化的代码示例:

unsigned bzhi32(unsigned value, int nbBits)
{
    return value & ((1u << nbBits) - 1);
}

clang可以轻松生成bzhi指令,而我目前还没有发现gcc有类似的结果:https://godbolt.org/g/jYrh8F

我想知道这是否可能。 这种能力至少已被请求,但不确定是否已完成。 如果是,也许代码片段中只存在一些微妙的问题,例如类型或属性,可以修复以使gcc成功进行此转换。

编辑:根据@chux的建议,为常量添加了u,尽管它仍然是一个不包含bzhi的4条指令函数。


1
请注意:移位无符号值通常会更少出现问题:使用 u 来添加 (1u << nbBits)-1。请注意,以下 Stack Overflow 回答 使用了无符号 1 而不是 int 类型的 1。 - chux - Reinstate Monica
如果你无法将编译器转换为所需的形式,而#ifdef也不适用,那么在某个时候,你必须在可移植性和性能之间做出选择 - 因为它们经常是相互冲突的目标。 - Mysticial
我目前正在使用 #ifdef,尝试寻找更好的解决方案。 - Cyan
Gcc的ifuncs可能很适合这个问题 - 就可移植性而言,它们还好吗? - Mark Plotnick
将您的特殊函数(函数包装器)设置为“static inline”,将它们放入单独的头文件中,并使用“#ifdef”魔法将硬件特定的子头文件包含进来,就像gcc/icc/clang实现内部函数一样,这是我经验中最好的选择,特别是对于知道自己硬件的最终用户管理员,他们可以调整代码以适应自己的硬件。请记住:可移植性不需要“即插即用”;通常最好使其在任何架构上都能正确运行,并且易于调整到任何架构。 - Nominal Animal
显示剩余2条评论
1个回答

2
截至2018年1月,gcc尚未实现此优化(有一个功能请求)。您可以通过使用内置函数来获取指令:
#include <x86intrin.h>

unsigned bzhi32(unsigned value, int nbBits) {
   return _bzhi_u32(value, nbBits);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接