Se gfortran o ifort compiladores sabiamente el uso de instrucciones SIMD cuando se suma el producto de dos matrices?

StackOverflow https://stackoverflow.com//questions/21050913

Pregunta

Tengo un código, escrito con numpy, y estoy considerando la posibilidad de portarlo a Fortran para un mejor rendimiento.

Una operación hago varias veces es sumar el elemento sabio producto de dos matrices:

sum(A*B)

Parece fundida multiplicar-agregar las instrucciones para ayudar con esto.Mi actual procesador no es compatible con estas instrucciones, así que no puedo probar cosas todavía.Sin embargo, puedo actualizar a un nuevo procesador que no admite FMA3 (un Intel Haswell procesador).

¿Alguien sabe si compilar el programa con "-march=native" (o el ifort equivalente) será suficiente para que el compilador (ya sea gfortran o ifort) el uso inteligente instrucciones SIMD para optimizar ese código, ¿o crees que voy a tener al bebé, los compiladores o el código?

¿Fue útil?

Solución 3

Gracias a Xiaolei de Zhu punta, ahora sé que gfortran utilizará fusionado multiplicar-agregar a optimizar sum(A*B).Por ejemplo, con este código:

programa de prueba implícito ninguno

real, dimension(7) ::a, b

un = (/ 2.0, 3.0, 5.0, 7.0, 11.0, 13.0, 17.0 /)

b = (/ 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0 /)

print *, suma(a*b)
endprogram

Puedo compilar con f95 sum.f95 -o sum -O3 -march=core-avx2, y objdump -d sum | grep vfmadd muestra

40088b:c4 e2 71 99 44 24 30 vfmadd132ss 0x30(%der),%xmm1,%xmm0

400892:c4 e2 69 b9 44 24 34 vfmadd231ss 0x34(%der),%xmm2,%xmm0

400899:c4 e2 61 b9 44 24 38 vfmadd231ss 0x38(%der),%xmm3,%xmm0

4008a0:c4 e2 59 b9 44 24 3c vfmadd231ss 0x3c(%der),%xmm4,%xmm0

4008a7:c4 e2 51 b9 44 24 40 vfmadd231ss 0x40(%der),%xmm5,%xmm0

4008ae:c4 e2 49 b9 44 24 44 vfmadd231ss 0x44(%der),%xmm6,%xmm0

4008b5:c4 e2 41 b9 44 24 48 vfmadd231ss 0x48(%der),%xmm7,%xmm0

Así gfortran desenrolla el lazo y poner en 7 fusionado multiplicar-agregar instrucciones.Si puedo crear más grande, al azar, matrices multidimensionales, todavía veo vfmadd231ss pop-up una vez (para que no desenrollar el bucle).

Otros consejos

Si usted utiliza -march=native en una máquina con SIMD, el compilador debe generar instrucciones SIMD, aunque yo siempre he utilizado -xHost indicador de lugar con ifort.

Pero yo no estoy tan seguro de cómo hacer que ellos lo hagan "con prudencia".Mi sensación es que en -O3 nivel ifort y gfortran ambos tienden a ser demasiado agresivo en la vectorización (es decir, usan la SIMD funcionalidad, más a menudo de lo que debería).Muy a menudo tengo que apagar la vectorización para obtener el código más eficiente.Esto, por supuesto, puede o no puede ser verdad para usted.

Normalmente es mejor utilizar el vector de las bibliotecas que están optimizados para esta tarea.Puede utilizar vdmul en MKL o gsl_vector_mul en GSL para ello.

El uso de -march=NEWARCH el resultado será un código de sintonía para la arquitectura NEWARCH pero no se puede ejecutar en una versión anterior de la arquitectura.Usted puede utilizar el -mtune=NEWARCH bandera donde NEWARCH es la arquitectura de su nuevo procesador.Esto va a generar código atentos a la nueva arquitectura, pero aún ejecutable en el antiguo.Dado que aún no tienes la nueva máquina, -mtune es probablemente lo que usted necesita en el momento.

Con ifort puede utilizar vectorización informe banderas para mostrar que parte del programa ha sido vectorizados.Por ejemplo, ifort bandera -vec-report=1 le dará esa información durante la compilación.Estoy seguro que no va a ser un equivalente de la bandera en gfortran.

gfortran versiones, donde sum(a*b) dio una mejor vectorización de dot_product(a,b) son de larga obsoletos.El código que muestran es el uso de serie AVX2 fma instrucciones.

En la aplicación de dot_product sin indirecto de indexación o de otras complicaciones (un simple bucle por sí mismo), fma probablemente será más lento que la combinación de simd multiplicaciones y añadir instrucciones, porque al multiplicar se puede hacer fuera de la latencia de la ruta crítica.gfortran uso de paralelo simd fma para dot_product puede ser muy eficaz en los casos más complicados.

Usted necesitará -O2 -ftree-vectorize -ffast-math -march=native or -O3 -ffast-math -march=native (así como vector de longitud) para vectorizar esta, y gfortran puede fallar para vectorizar dentro de una región paralela de OpenMP.

gfortran 4.9 parece haber descartado la opción -ftree-vectorizador-verbose.-fdump-árbol-vect escribe los detalles de la vectorización se la pasa a un .vect archivo, con diferentes nombres elegidos para los diferentes gcc versiones.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top