我想尝试一些x86 BMI设置的intrinsic。grep bmi /proc/cpuinfo
在我的AMD Ryzen CPU中显示bmi1
和bmi2
。但我无法获得clang来编译一些指令,特别是BLSI和BLSR。看起来它们在clang's bmiintrin.h
中不受支持。这是真的吗?还是我错过了什么?一般来说,你是否需要安装某种来自Intel/AMD的LLVM“插件”或类似的东西来使用CPU特定的功能?在这种情况下,使用他们的构建工具更好吗?
在this article之后,我用BLSI或BLSR构造了一个测试程序:
// test_bmi.c
#include <x86intrin.h>
// not #include <bmiintrin.h> - clang errors and asks for x86intrin.h
volatile unsigned long long result;
main() {
...
for (unsigned long long i=0; i<max_count; i++) {
result = _blsi_u64(i);
}
}
字符串
它是用-march=native
构建的,可以打开所有CPU功能:
clang -march=native test_bmi.c -o test_bmi
型
但是在objdump -d test_bmi
汇编中没有类似blsi
的指令。看看the bliintrin.h source,似乎实际上不支持BLSI和BLSR指令:
static __inline__ unsigned long long __DEFAULT_FN_ATTRS
__blsi_u64(unsigned long long __X)
{
return __X & -__X;
}
型
但是,例如,BEXTR在头文件中,它确实显示在objdump
程序集中:
static __inline__ unsigned long long __DEFAULT_FN_ATTRS
__bextr_u64(unsigned long long __X, unsigned long long __Y)
{
return __builtin_ia32_bextr_u64(__X, __Y);
}
$ objdump -d test_bmi | grep bextr
12c5: c4 e2 f0 f7 c0 bextr %rcx,%rax,%rax
型
这是否意味着clang并不真正支持BLSI和BLSR指令?这是故意的,还是我错过了一些东西来启用它们?
1条答案
按热度按时间k5ifujac1#
不需要特殊的intrinsic,因为clang知道使用这些指令和其他类似的指令(包括
andn
,bextr
,popcnt
(!),blsi
,blsmsk
,blsr
和tzcnt
(!)等),如果你只是在C中编写它们的行为。例如,你可以写
字符串
编译器会把它变成
型
这种窥视孔分析非常强大,甚至可以识别
popcnt
(包括循环和位操作),tzcnt
和类似指令的常见实现。因此,只需像平常一样编写代码,并为支持您正在寻找的指令的目标体系结构进行编译。编译器将在适当的地方自动使用它们。
请注意,您可能需要使用优化进行编译,以使这些优化触发;这可以解释您最初未能生成
blsi
的原因。