我使用两台计算机工作。一种不支持 AVX,另一种支持 AVX。让我的代码在运行时找到我的CPU支持的指令集并选择合适的代码路径会很方便。
我按照 Agner Fog 的建议制作了一个 CPU 调度程序(http://www.agner.org/optimize/#vectorclass 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 一起使用。阿格纳·福格的手册说
“使用 256 位浮点向量类(Vec8f、
Vec4d)除非指定AVX指令集,但是可以方便使用
无论如何,无论是否使用 AVX 使用相同的源代码,这些类都是如此。
每个 256 位向量在编译时将简单地分为两个 128 位向量
没有 AVX。”
然而,当我有两个带有 Vec8f 的源文件时,一个是用 SSE2 编译的,另一个是用 AVX 编译的,然后我就崩溃了。
编辑2:
我可以从命令行让它工作
>cl -c sse2.cpp
>cl -c /arch:AVX avx.cpp
>cl foo.cpp sse2.obj avx.obj
>foo.exe
编辑3:
然而,这会崩溃
>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 系统),但至少它不会崩溃。