与AVX / AVX2一起使用的OS X的最低版本是多少?

时间:2016-07-12 02:47:19

标签: macos sse avx avx2

我有一个图像绘制程序,它为SSE,SSE2,SSE3,SSE4.1,SSE4.2,AVX和AVX2多次编译。 我的程序通过检查CPUID标志来动态调度其中一个二进制变量。

在Windows上,如果操作系统不支持,我会检查Windows版本并禁用AVX / AVX2调度。 (例如,只有Windows 7 SP1或更高版本支持AVX / AVX2。)

我想在Mac OS X上做同样的事情,但我不确定哪个版本的OS X支持AVX / AVX2。

请注意,我想知道的是用于AVX / AVX2的OS X的最低版本。不是能够AVX / AVX2的机器型号。

2 个答案:

答案 0 :(得分:4)

为了检测指令集功能,我引用了两个源文件:

  1. Mysticial的cpu_x86.cpp
  2. Agner Fog的instrset_detect.cpp
  3. 如果您的操作系统支持AVX和其他功能,这两个文件都将告诉您如何通过AVX2以及XOP,FMA3,FMA4检测SSE。

    我习惯了Agner的代码(MSVC,GCC,Clang,ICC的一个源文件),所以我们先来看看。

    以下是来自instrset_detect.cpp的用于检测AVX的相关代码片段:

    iset = 0;                                              // default value
    int abcd[4] = {0,0,0,0};                               // cpuid results
    cpuid(abcd, 0);                                        // call cpuid function 0
    //....
    iset = 6;                                              // 6: SSE4.2 supported
    if ((abcd[2] & (1 << 27)) == 0) return iset;           // no OSXSAVE
    if ((xgetbv(0) & 6) != 6)       return iset;           // AVX not enabled in O.S.
    if ((abcd[2] & (1 << 28)) == 0) return iset;           // no AVX
    iset = 7;                                              // 7: AVX supported
    

    xgetbv定义为

    // Define interface to xgetbv instruction
    static inline int64_t xgetbv (int ctr) {    
    #if (defined (_MSC_FULL_VER) && _MSC_FULL_VER >= 160040000) || (defined (__INTEL_COMPILER) && __INTEL_COMPILER >= 1200) // Microsoft or Intel compiler supporting _xgetbv intrinsic
    
        return _xgetbv(ctr);                                   // intrinsic function for XGETBV
    
    #elif defined(__GNUC__)                                    // use inline assembly, Gnu/AT&T syntax
    
       uint32_t a, d;
       __asm("xgetbv" : "=a"(a),"=d"(d) : "c"(ctr) : );
       return a | (uint64_t(d) << 32);
    
    #else  // #elif defined (_WIN32)                           // other compiler. try inline assembly with masm/intel/MS syntax
    
      //see the source file
    }
    

    我没有包含cpuid函数(请参阅源代码),我从xgetbv删除了非GCC内联汇编,以缩短答案。

    以下是来自Mysticial detect_OS_AVX()的{​​{1}}用于检测AVX:

    cpu_x86.cpp

    Mystical显然是从this answer提出了这个解决方案。

    请注意,两个源文件基本相同:检查OSXSAVE位27,从CPUID检查AVX位28,检查bool cpu_x86::detect_OS_AVX(){ // Copied from: http://stackoverflow.com/a/22521619/922184 bool avxSupported = false; int cpuInfo[4]; cpuid(cpuInfo, 1); bool osUsesXSAVE_XRSTORE = (cpuInfo[2] & (1 << 27)) != 0; bool cpuAVXSuport = (cpuInfo[2] & (1 << 28)) != 0; if (osUsesXSAVE_XRSTORE && cpuAVXSuport) { uint64_t xcrFeatureMask = xgetbv(_XCR_XFEATURE_ENABLED_MASK); avxSupported = (xcrFeatureMask & 0x6) == 0x6; } return avxSupported; } 的结果。

答案 1 :(得分:2)

对于AVX,答案非常简单:

至少需要OS X 10.6.7

请注意,只有10J3250和10J4138才能支持它。

对于AVX2,即10.8.4 build 12E3067或12E4022