¿Cómo detectar la disponibilidad de SSE/SSE2/AVX/AVX2/AVX-512/AVX-128-FMA/KCVI en tiempo de compilación?


Estoy tratando de optimizar algunos matriz de cómputos y me preguntaba si era posible detectar en tiempo de compilación si SSE/SSE2/AVX/AVX2/AVX-512/AVX-128-FMA/KCVI[1] está habilitado por el compilador ? Idealmente para GCC y Clang, pero puedo manejarlo con solo uno de ellos.

No estoy seguro de que sea posible y quizás use mi propia macro, pero preferiría detectarla y pedirle al usuario que la seleccione.


[1] "KCVI" significa Caballeros Vector Esquina Optimizaciones de instrucciones. Las bibliotecas como FFTW detectan / utilizan estas nuevas optimizaciones de instrucciones.

Author: Trevor Boyd Smith, 2015-03-09

1 answers

La mayoría de los compiladores definirán automáticamente:

__SSE__
__SSE2__
__SSE3__
__AVX__
__AVX2__

Etc, de acuerdo con cualquier interruptor de línea de comandos que esté pasando. Puede comprobar esto fácilmente con gcc (o compiladores compatibles con gcc como clang), así:

$ gcc -msse3 -dM -E - < /dev/null | egrep "SSE|AVX" | sort
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE2_MATH__ 1
#define __SSE3__ 1
#define __SSE_MATH__ 1

O:

$ 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

O simplemente para comprobar las macros predefinidas para una compilación predeterminada en su plataforma particular:

$ gcc -dM -E - < /dev/null | egrep "SSE|AVX" | sort
#define __SSE2_MATH__ 1
#define __SSE2__ 1
#define __SSE3__ 1
#define __SSE_MATH__ 1
#define __SSE__ 1
#define __SSSE3__ 1

Los procesadores Intel más recientes admiten AVX-512, que no es un conjunto de instrucciones monolítico. Se puede ver el soporte disponible de GCC (versión 6.2) para dos ejemplos a continuación.

Aquí está el Desembarco de los Caballeros:

$ 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

Aquí está 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

Intel ha revelado subconjuntos AVX-512 adicionales (ver extensiones ISA ). GCC (versión 7) admite banderas de compilador y símbolos de preprocesador asociados con los subconjuntos 4FMAPS, 4VNNIW, IFMA, VBMI y VPOPCNTDQ de AVX-512:

for i in 4fmaps 4vnniw ifma vbmi vpopcntdq ; do echo "==== $i ====" ; gcc -mavx512$i -dM -E - < /dev/null | egrep "AVX512" | sort ; done
==== 4fmaps ====
#define __AVX5124FMAPS__ 1
#define __AVX512F__ 1
==== 4vnniw ====
#define __AVX5124VNNIW__ 1
#define __AVX512F__ 1
==== ifma ====
#define __AVX512F__ 1
#define __AVX512IFMA__ 1
==== vbmi ====
#define __AVX512BW__ 1
#define __AVX512F__ 1
#define __AVX512VBMI__ 1
==== vpopcntdq ====
#define __AVX512F__ 1
#define __AVX512VPOPCNTDQ__ 1
 68
Author: Paul R,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-18 00:23:28