fullmetal episodes diferencia brotherhood anime alchemist adaptaciones c++ visual-c++ x86 avx fma

c++ - episodes - fullmetal alchemist brotherhood wikipedia



Generar automáticamente instrucciones de FMA en MSVC (2)

MSVC 2015 genera una instrucción fma para operaciones escalares pero no para operaciones vectoriales (a menos que uses explícitamente un fma intrínseco).

Recopilé el siguiente código

//foo.cpp float mul_add(float a, float b, float c) { return a*b + c; } //MSVC cannot handle vectors as function parameters so use const references __m256 mul_addv(__m256 const &a, __m256 const &b, __m256 const &c) { return _mm256_add_ps(_mm256_mul_ps(a, b), c); }

con

cl /c /O2 /arch:AVX2 /fp:fast /FA foo.cpp

en MSVC2015 y produjo el siguiente ensamblaje

;mul_add vmovaps xmm3, xmm1 vfmadd213ss xmm3, xmm0, xmm2 vmovaps xmm0, xmm3

y

;mul_addv vmovups ymm0, YMMWORD PTR [rcx] vmulps ymm1, ymm0, YMMWORD PTR [rdx] vaddps ymm0, ymm1, YMMWORD PTR [r8]

MSVC admite las instrucciones AVX / AVX2 desde hace años y de acuerdo con esta publicación de blog msdn , puede generar automáticamente instrucciones fusionadas-multiplicar-añadir (FMA) .

Sin embargo, ninguna de las siguientes funciones compila a la instrucción FMA:

float func1(float x, float y, float z) { return x * y + z; } float func2(float x, float y, float z) { return std::fma(x,y,z); }

Peor aún, std :: fma no se implementa como una única instrucción FMA, funciona terriblemente, mucho más lento que un simple x * y + z (se espera un rendimiento deficiente de std :: fma si la implementación no se basa en FMA instrucción).

/arch:AVX2 /O2 /Qvec banderas /arch:AVX2 /O2 /Qvec . También lo intenté con /fp:fast , sin éxito.

Entonces, la pregunta es ¿cómo puede MSVC obligarse a emitir instrucciones de FMA automáticamente?

ACTUALIZAR

Hay un #pragma fp_contract (on|off) , que (parece) no hace nada.


Resolví este problema de larga data.

Como resultado, flags /fp:fast , /arch:AVX2 y /O1 (o superior /O1 ) no son suficientes para que el modo Visual Studio 2015 emita instrucciones FMA en modo de 32 bits. También necesita activar la "optimización de todo el programa" con flag /GL .

Entonces Visual Studio 2015 generará una instrucción FMA vfmadd213ss para

float func1(float x, float y, float z) { return x * y + z; }

En cuanto a std::fma , abrí un error en Microsoft Connect . Confirmaron el comportamiento que std::fma no compila en las instrucciones de FMA, porque el compilador no lo trata como un elemento intrínseco. De acuerdo con su respuesta, se solucionará en una actualización futura para obtener el mejor codegen posible.