在非haswell处理器上禁用AVX2功能

Disable AVX2 functions on non-Haswell processors

本文关键字:AVX2 功能 haswell 处理器 在非      更新时间:2023-10-16

我写了一些AVX2代码在Haswell i7处理器上运行。在非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。谢谢你的帮助。

我不认为这是一个好主意单独执行,除非你不得不。在您的示例中,您可以创建一个CPU调度程序。我最近为GCC和Visual studio做了这个。

假设您有一个用于SSE和AVX的名为product的函数。将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。这样,您就不必拥有单独的可执行文件。

如果您只想在编译时执行此操作,则可以这样做:

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

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

如果你想做运行时调度那就有点复杂了