与 AVX/AVX2 一起使用的 OS X 的最低版本是什么?
What is the minimum version of OS X for use with AVX/AVX2?
我有一个针对 SSE、SSE2、SSE3、SSE4.1、SSE4.2、AVX 和 AVX2 多次编译的图像绘制例程。
我的程序通过检查 CPUID 标志动态调度这些二进制变体之一。
在 Windows 上,我检查 Windows 的版本并在 OS 不支持时禁用 AVX/AVX2 调度。 (例如,只有Windows 7 SP1或更高版本支持AVX/AVX2。)
我想在 Mac OS X 上做同样的事情,但我不确定 OS X 的哪个版本支持 AVX/AVX2.
请注意,我想知道的是与 AVX/AVX2 一起使用的 OS X 的最低版本。不是能够 AVX/AVX2.
的机器型号
对于 AVX,答案非常简单:
您至少需要 OS X 10.6.7
请注意,只有 build 10J3250 和 10J4138 支持它。
对于 10.8.4 构建 12E3067 或 12E4022 的 AVX2
为了检测指令集功能,我参考了两个源文件:
- 神秘主义者的cpu_x86.cpp
- 阿格纳雾的 instrset_detect.cpp
如果您的 OS 支持 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 cpu_x86.cpp
的 detect_OS_AVX()
用于检测 AVX 的 detect_OS_AVX()
:
bool cpu_x86::detect_OS_AVX(){
// Copied from:
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;
}
Mystical 显然从 this answer.
提出了这个解决方案
请注意,两个源文件的作用基本相同:检查 OSXSAVE 位 27,检查 CPUID 的 AVX 位 28,检查 xgetbv
.
的结果
我有一个针对 SSE、SSE2、SSE3、SSE4.1、SSE4.2、AVX 和 AVX2 多次编译的图像绘制例程。 我的程序通过检查 CPUID 标志动态调度这些二进制变体之一。
在 Windows 上,我检查 Windows 的版本并在 OS 不支持时禁用 AVX/AVX2 调度。 (例如,只有Windows 7 SP1或更高版本支持AVX/AVX2。)
我想在 Mac OS X 上做同样的事情,但我不确定 OS X 的哪个版本支持 AVX/AVX2.
请注意,我想知道的是与 AVX/AVX2 一起使用的 OS X 的最低版本。不是能够 AVX/AVX2.
的机器型号对于 AVX,答案非常简单:
您至少需要 OS X 10.6.7
请注意,只有 build 10J3250 和 10J4138 支持它。
对于 10.8.4 构建 12E3067 或 12E4022 的 AVX2
为了检测指令集功能,我参考了两个源文件:
- 神秘主义者的cpu_x86.cpp
- 阿格纳雾的 instrset_detect.cpp
如果您的 OS 支持 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 cpu_x86.cpp
的 detect_OS_AVX()
用于检测 AVX 的 detect_OS_AVX()
:
bool cpu_x86::detect_OS_AVX(){
// Copied from:
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;
}
Mystical 显然从 this answer.
提出了这个解决方案请注意,两个源文件的作用基本相同:检查 OSXSAVE 位 27,检查 CPUID 的 AVX 位 28,检查 xgetbv
.