大多数编译器将自动定义:
__SSE__
__SSE2__
__SSE3__
__AVX__
__AVX2__
根据您传递的任何命令行开关,等等。您可以使用gcc(或gcc兼容的编译器,如clang)轻松检查此内容,方法如下:
$ gcc -msse3 -dM -E - < /dev/null | egrep "SSE|AVX" | sort
或者:
$ gcc -mavx2 -dM -E - < /dev/null | egrep "SSE|AVX" | sort
#define __AVX__ 1
#define __AVX2__ 1
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE2_MATH__ 1
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSE_MATH__ 1
#define __SSSE3__ 1
或者只需检查针对您特定平台的默认构建的预定义宏:
$ gcc -dM -E - < /dev/null | egrep "SSE|AVX" | sort
较新的英特尔处理器支持AVX-512,这不是一个单olithic的指令集。您可以看到GCC(版本6.2)支持以下两个示例。
这里是骑士着陆:
$ gcc -march=knl -dM -E - < /dev/null | egrep "SSE|AVX" | sort
#define __AVX__ 1
#define __AVX2__ 1
#define __AVX512CD__ 1
#define __AVX512ER__ 1
#define __AVX512F__ 1
#define __AVX512PF__ 1
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE2_MATH__ 1
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSE_MATH__ 1
#define __SSSE3__ 1
这里是Skylake AVX-512:
$ gcc -march=skylake-avx512 -dM -E - < /dev/null | egrep "SSE|AVX" | sort
#define __AVX__ 1
#define __AVX2__ 1
#define __AVX512BW__ 1
#define __AVX512CD__ 1
#define __AVX512DQ__ 1
#define __AVX512F__ 1
#define __AVX512VL__ 1
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE2_MATH__ 1
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSE_MATH__ 1
#define __SSSE3__ 1
英特尔已经披露了额外的AVX-512子集(请参见ISA扩展)。GCC(7版本)支持与AVX-512的4FMAPS,4VNNIW,IFMA,VBMI和VPOPCNTDQ子集相关的编译器标志和预处理器符号:
for i in 4fmaps 4vnniw ifma vbmi vpopcntdq ; do echo "==== $i ====" ; gcc -mavx512$i -dM -E - < /dev/null | egrep "AVX512" | sort ; done
==== 4fmaps ====
==== 4vnniw ====
==== ifma ====
==== vbmi ====
==== vpopcntdq ====
请注意,SSE宏在Visual C++中不起作用。您必须使用 _M_IX86_FP
。