我用两台电脑工作。一种不支持 AVX,一种支持 AVX。让我的代码在运行时找到我的 CPU 支持的指令集并选择适当的代码路径会很方便。我已经按照 Agner Fog 的建议制作了一个 CPU 调度程序(http://www.agner.org/optimize/#vectorclass)。但是,在我没有 AVX 编译和与 Visual Studio 链接的情况下,启用 AVX 的代码会导致代码在我运行时崩溃。
我的意思是,例如,我有两个源文件,一个是 SSE2 指令集,其中定义了一些 SSE2 指令,另一个是定义了 AVX 指令集和一些 AVX 指令。在我的主函数中,如果我只引用 SSE2 函数,代码仍然会由于启用了 AVX 和 AVX 指令的任何源代码而崩溃。关于如何解决这个问题的任何线索?
编辑:好的,我想我隔离了这个问题。我正在使用 Agner Fog 的矢量类,并将三个源文件定义为:
//file sse2.cpp - compiled with /arch:SSE2
#include "vectorclass.h"
float func_sse2(const float* a) {
Vec8f v1 = Vec8f().load(a);
float sum = horizontal_add(v1);
return sum;
}
//file avx.cpp - compiled with /arch:AVX
#include "vectorclass.h"
float func_avx(const float* a) {
Vec8f v1 = Vec8f().load(a);
float sum = horizontal_add(v1);
return sum;
}
//file foo.cpp - compiled with /arch:SSE2
#include <stdio.h>
extern float func_sse2(const float* a);
extern float func_avx(const float* a);
int main() {
float (*fp)(const float*a);
float a[] = {1,2,3,4,5,6,7,8};
int iset = 6;
if(iset>=7) {
fp = func_avx;
}
else {
fp = func_sse2;
}
float sum = (*fp)(a);
printf("sum %f\n", sum);
}
这崩溃了。如果我改为在 func_SSE2 中使用 Vec4f 它不会崩溃。我不明白这一点。只要我没有另一个带有 AVX 的源文件,我就可以单独使用 Vec8f 和 SSE2。阿格纳雾的手册说
“除非指定了 AVX 指令集,否则使用 256 位浮点向量类(Vec8f、Vec4d)没有任何优势,但如果在有和没有 AVX 的情况下使用相同的源代码,则无论如何使用这些类会很方便。在没有 AVX 的情况下编译时,每个 256 位向量将简单地分成两个 128 位向量。”
但是,当我有两个使用 Vec8f 的源文件时,一个使用 SSE2 编译,一个使用 AVX 编译,然后我会崩溃。
Edit2:我可以从命令行让它工作
>cl -c sse2.cpp
>cl -c /arch:AVX avx.cpp
>cl foo.cpp sse2.obj avx.obj
>foo.exe
Edit3:但是,这会崩溃
>cl -c sse2.cpp
>cl -c /arch:AVX avx.cpp
>cl foo.cpp avx.obj sse2.obj
>foo.exe
另一个线索。显然,链接的顺序很重要。如果 avx.obj 在 sse2.obj 之前它会崩溃,但如果 sse2.obj 在 avx.obj 之前它不会崩溃。我不确定它是否选择了正确的代码路径(我现在无法访问我的 AVX 系统),但至少它不会崩溃。