我最近一直在各种编译器上对一些快速数字代码进行基准测试,并对某些编译器在最大优化 -O2 和 AVX/AVX2 代码生成时速度的系统性变化感到震惊。我将其中一些缩小到一个奇怪的行为,而不是设置最快的代码生成器与其他代码生成器分开。
也就是说,在启用 AVX 代码生成的情况下,-O2 Clang 和 ICX 将对
fminf/fmin
的内联调用作为 minss
,而包的其余部分 GCC、ICC 和 MSVC 顽固地继续 call fminf
。他们都很高兴地内联fabsf/fabs
好吧。
MRE 的代码如下,如果我做得正确的话,这是 Godbolt 上的链接,您可以在各种编译器上尝试它。 Clang 和 Intel 的 ICX 似乎将它内联到我能找到的编译器来测试。
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
float y, x = 2.0;
y = 10*rand()-5;
y = fabs(y);
if (x < y) y = x;
printf("%g", y);
y = 10 * rand();
y = fminf(x,y);
printf("%g", y);
}
汇总表如下:
编译器 | 内联
|
---|---|
海湾合作委员会13.2 | 不 |
ICC最新 | 不 |
MSVC 2022 x64 | 不 |
叮当17.0.1 | 是的 |
ICX | 是的 |
fmin
和 fmax
出现在相当多的数值优化代码中,因此速度减慢可能相当显着。一旦你知道了,就可以通过定义宏 FMIN
和 FMAX
来解决这个问题。如果其他编译器内联它就好了。
我想不出为什么某些编译器中缺少这种特定优化的任何原因......有人有解释吗?
fabs
是一个更复杂的情况,并且在所有情况下都是内联的。