作为常见优化的一部分,我在每次编译时仅使用自动矢量化程序将用户编写的循环代码转换为SIMD指令所遇到的“问题”是,如果您更改编译器,则无法确定它是否也会自动-向量化代码的效果同样好。
因此,如果您只想针对单个处理器,那么我想让编译器为我生成针对特定功能的高级C代码,该功能使用x86内在包装函数来与不同的编译器供应商共同使用。
是否有反编译器,或者甚至是GCC的编译器选项都可以提供此代码?
答案 0 :(得分:3)
我不知道,但是Intel的内在指南可以通过asm助记符进行搜索。 https://software.intel.com/sites/landingpage/IntrinsicsGuide/。过滤掉AVX512通常有助于简化操作(因为使用AVX512内在函数的所有3种大小都有成千上万的{{1}} / _mask
)。
asm手册条目还列出了每条指令的助记符。 https://www.felixcloutier.com/x86/index.html
_maskz
有时可以帮助通过asm跟踪变量,但是通常在auto-vec之后,所有名称都将像-fverbose-asm
这样。不过,如果您在查看哪个指针被加载/存储到哪里时遇到麻烦,它会有所帮助。
您还可以让编译器吐出其内部表示形式,例如LLVM-IR或GIMPLE或RTL,但您不能只在x86手册中查找它们。我已经知道x86 asm,因此通常可以很容易地看到编译器在做什么,然后手动将其转换为内在函数。实际上,当clang发现gcc遗漏的一些聪明东西时,即使在源已经使用内部函数的情况下,我实际上已经做到了。或将纯C用于无法自动矢量化的标量代码,以便将gcc握住以clang的方式进行操作,反之亦然。
如果您正在使用clang,请使用tmp1234
进行编译,以矢量化而不是展开,因此asm的复杂性降低了。 (默认情况下,gcc默认不会展开)。
但是请注意,最佳自动矢量化选择取决于要调整的目标uarch。 clang或-fno-unroll-loops
(禅宗)将生成与gcc -O3 -march=znver1
不同的代码。尽管通常这只是128位和256位向量的问题,但实际上并不是不同的策略,除非可用的不同指令集允许一些新的东西。例如SSE4.1打包了32位整数乘法(不加宽32x32 => 64),并填充了许多元素大小和符号不足的部分。
如果要在将来的CPU微体系结构和扩展以及编译器方面不致于过时,那么以手动方式冻结矢量化并不一定是理想的。 >