禁用非Haswell处理器上的AVX2功能

时间:2014-05-15 11:04:47

标签: c++ sse avx2

我已经编写了一些在Haswell i7处理器上运行的AVX2代码。相同的代码库也用于非Haswell处理器,其中相同的代码应替换为其SSE等效代码。我想知道有没有办法让编译器忽略非Haswell处理器上的AVX2指令。我需要这样的东西:

public void useSSEorAVX(...){
    IF (compiler directive detected AVX2)
        AVX2 code (this part is ready)
    ELSE
        SSE code  (this part is also ready)
    }
}

现在我正在编译之前评论相关代码,但必须有一些更有效的方法来执行此操作。我正在使用Ubuntu和gcc。谢谢你的帮助。

2 个答案:

答案 0 :(得分:11)

除非必须,否则我认为制作单独的可执行文件不是一个好主意。在您的情况下,您可以制作CPU调度程序。我最近为GCC和Visual studio做了这个。

假设您有一个名为product的函数用于SSE和AVX。您将SSE版本放在文件product_SSE.cpp中,将AVX2版本放在文件product_AVX2.cpp中。您可以单独编译每个(例如-msse2-mavx2)。然后制作一个这样的模块:

extern "C" void product_SSE(float *a, float *b, float *c, int n);
extern "C" void product_AVX2(float *a, float *b, float *c, int n); 
           void product_dispatch(float *a, float *b, float *c, int n); 
void (*fp)(float* a, float *b, float *c, int n) = product_dispatch;

inline void product_dispatch(float *a, float *b, float *c, int n) {
    int iset = instrset_detect();
    if(iset==8) {
        fp = product_AVX2
    }
    else {
        fp = product_SSE
    }
    fp(a,b,c,n);
}

inline void product(float *a, float *b, float*c, int bs) {
    fp(a,b,c,n);
}

使用较低的公共指令集(例如,使用SSE2)编译该模块。现在,当您调用product时,它首先调用product_dispatch将函数指针fp设置为product_AVX2product_SSE,然后从函数指针调用该函数。第二次拨打product时,它会直接跳至product_AVX2product_SSE。这样您就不必拥有单独的可执行文件。

答案 1 :(得分:5)

如果您只想在编译时执行此操作,那么您可以执行此操作:

#ifdef __AVX2__
    // AVX2 code
#elif __SSE__
    // SSE code
#else
    // scalar code
#endif

请注意,使用gcc -mavx2 ...进行编译时,会自动定义__AVX2__。同样适用于__SSE__。 (另请注意,您可以使用咒语gcc -dM -E -mavx2 - < /dev/null检查编译器为任何给定命令行切换预定义的内容。)

如果你想进行运行时调度,那就更复杂了。