有没有可能让GCC自动向量化器输出内部函数而非汇编代码?

7

我认为仅仅使用自动向量化器将用户编写的循环代码在每次编译时转换为SIMD指令作为常规优化的一部分,存在一个“问题”,如果更换编译器,则无法确定它是否同样优秀地对您的代码进行自动向量化。

因此,如果你只想针对单个处理器进行优化,我希望编译器为特定函数生成高级C代码,该代码使用x86内置包装函数,这些函数与不同的编译器供应商通用。

是否存在反编译器,或者甚至是GCC的编译器选项,可以给我提供这种代码?

1个回答

4
我不知道有没有,但是英特尔的内在函数指南可以按汇编助记符进行搜索。https://software.intel.com/sites/landingpage/IntrinsicsGuide/。过滤掉AVX512通常有助于更轻松地浏览(因为AVX512内在函数有无数个_mask / _maskz,适用于所有3种大小)。
汇编手册条目还列出了每个指令的助记符。https://www.felixcloutier.com/x86/index.html -fverbose-asm有时可以帮助跟踪变量通过汇编,但通常在自动向量化后,所有内容都会像tmp1234这样命名。不过,如果您在查看哪个指针被加载/存储在哪里时遇到问题,它可能会有所帮助。
你也可以让编译器输出它们的内部表示,例如LLVM-IR或GIMPLE或RTL,但是你不能在x86手册中查找它们。我已经了解了x86汇编语言,所以通常可以很容易地看出编译器正在做什么,并将其手动转换为内置函数。当clang发现gcc错过了一些聪明的东西时,我实际上已经这样做了,即使源代码已经使用了内置函数。或者对于无法自动矢量化的标量代码,将其转换为纯C,以便手动指导gcc按照clang的方式执行,反之亦然。
使用-fno-unroll-loops编译,如果您使用的是clang,则进行矢量化但不展开,这样汇编代码会更简单。(gcc一开始就没有展开)。但请注意,最佳自动矢量化选择取决于您正在调整的目标uarch。clang或gcc -O3 -march=znver1(Zen)将产生不同于-march=skylake的代码。虽然通常只涉及128位与256位向量的问题,除非可用的指令集允许出现新的策略。例如,SSE4.1具有打包的32位整数乘法(不扩大32x32 => 64),并填充了很多元素大小和符号缺失的地方。如果您希望针对未来的CPU微架构和扩展以及编译器做好准备,固定矢量化的方式不一定是理想的。

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