我目前正在再次比较编译器。我的目标主要是通过AVX2 / AVX512优化实现非常简单的DSP循环,例如:
for (int i=0; i<cnt; i++) x[i] = sin(y[i]) * z[i];
我发现CLANG经常远远胜过MSVC 2017和Intel编译器2019,尤其是在使用AVX内部函数的情况下。但是,只要有不可思议的数学函数(例如sin,cos,sqrt,ln,exp),CLANG就会严重失败,提供4x-10x的慢速代码。似乎ICL和MSVC都在以某种方式扩展SSE / AVX指令,但CLANG可能不是。我的安装是否有问题或其他解决方法?
=============================
最小示例:
#include <math.h>
#include <stdio.h>
#include <Windows.h>
__declspec(noinline) void FN(float* x, int cnt)
{
for (int i=0; i<cnt; i++) x[i] = sinf(x[i]);
};
int main(int argc, char* argv[])
{
DWORD start = ::GetTickCount();
__declspec(align(64)) float x[256];
for (int i=0; i<256; i++) x[i] = (float)i;
for (int iter=0; iter<20000000; iter++) FN(x, 256);
DWORD end = ::GetTickCount();
printf("%i\n", end - start);
float sum = 0;
for (int i=0; i<256; i++) sum += x[i];
printf("%f\n", sum);
return 1;
};
我使用了CLANG(LLVM 7.0.0)标志:
-fno-rtti -arch x86_64 "-D MARCHITECTURE_AVX512" -mavx512f -fasm-blocks -stdlib=libstdc++ -mfpmath=sse -ffast-math -march=native -fno-math-errno -O3 -fdata-sections -ffunction-sections
CLANG会生成一些疯狂的代码,其中充满了对各种功能的调用,在某些情况下,甚至看起来像是在混合SSE2和AVX指令集。 MSVC创建对sinf8的调用循环,其中包含一个不错的简单AVX2代码,可一次计算8次正弦波。在这里,MSVC代码大约需要5秒钟,CLANG大约需要12秒钟。