2010-11-08 9 views
13

He leído el libro Fortran 95 de Metcalf, Reid and Cohen, y Numerical Recipes en Fortran 90. Recomiendan utilizar WHERE, FORALL y SPREAD entre otras cosas para evitar la serialización innecesaria de su programa.¿Las construcciones de Fortran 95 como WHERE, FORALL y SPREAD generalmente dan como resultado un código paralelo más rápido?

Sin embargo, me encontré con this answer que afirma que FORALL es bueno en teoría, pero inútil en la práctica; también podría escribir bucles ya que paralelizan igual de bien y puede paralelizarlos explícitamente usando OpenMP (o funciones automáticas de algunos compiladores como Intel).

¿Alguien puede verificar por experiencia si generalmente han encontrado estas construcciones para ofrecer ventajas sobre los bucles explícitos y si las declaraciones en términos de rendimiento paralelo?

¿Y hay otras características paralelas del lenguaje que son buenas en principio pero que no valen la pena en la práctica?

Aprecio que las respuestas a estas preguntas sean de alguna manera dependientes de la implementación, así que estoy más interesado en gfortran, las CPU Intel y el paralelismo SMP.

Respuesta

13

Como dije en mi respuesta a la otra pregunta, no es un general creencia de que FORALL no ha sido tan útil como se esperaba cuando se introdujo en el lenguaje. Como ya se explicó en otras respuestas, tiene requisitos restrictivos y un papel limitado, y los compiladores se han vuelto bastante buenos para optimizar bucles regulares. Los compiladores siguen mejorando, y las capacidades varían de compilador a compilador. Otra pista es que Fortran 2008 está intentando de nuevo ... además de agregar paralelización explícita al lenguaje (co-arrays, ya mencionado), también hay "do concurrent", una nueva forma de bucle que requiere restricciones que deberían permitir mejor al compilador para realizar optimizaciones de paralaje automáticas, sin embargo, debe ser lo suficientemente general como para ser útil - ver ftp://ftp.nag.co.uk/sc22wg5/N1701-N1750/N1729.pdf.

En cuanto a la obtención de velocidad, la mayoría selecciono buenos algoritmos y un programa para la legibilidad & facilidad de mantenimiento. Solo si el programa es demasiado lento, ubico los cuellos de botella y recodo o implemento multi-threading (OpenMP). Será un caso raro donde FORALL o WHERE versus un do loop explícito tendrán una diferencia significativa de velocidad; me gustaría ver más claramente cuán clara es la intención del programa.

6

He examinado superficialmente esto y, triste de informar, generalmente encuentro que la escritura de mis bucles da como resultado explícitamente programas más rápidos que las construcciones paralelas sobre las que escribe. Incluso asignaciones de matriz completa simples como A = 0 generalmente son superadas por do-loops.

No tengo ningún dato a la mano y si lo hiciera, estaría desactualizado. Realmente debería incluir todo esto en un conjunto de pruebas y volver a intentarlo; los compiladores sí mejoran (a veces también empeoran).

Todavía utilizo las construcciones paralelas, especialmente las operaciones de conjunto completo, cuando son la forma más natural de expresar lo que estoy tratando de lograr. Nunca he probado estos constructos dentro de las construcciones de trabajo compartido de OpenMP. Realmente debería hacerlo.

+0

No pregunté acerca de las operaciones de matriz completa porque en muchos casos hacen que el código sea más claro, por lo que incluso sin ganancia de rendimiento las usaría de todos modos. Spread crea una dimensión extra a lo largo de una matriz y copia la matriz a lo largo de ella: http://www.liv.ac.uk/HPC/HTMLF90Course/HTMLF90CourseNotesnode259.html. Con respecto a las pruebas de rendimiento, estoy menos interesado en optimizar un caso particular y más interesado en encontrar el mejor enfoque general para comenzar antes de comenzar a optimizar. – DaveP

0

En teoría, el uso de tales asignaciones le permite al compilador saber lo que quiere hacer y debería permitirle optimizarlo mejor. En la práctica, vea la respuesta de Mark ... También creo que es útil si el código se ve más limpio de esa manera. He usado cosas como FORALL mismo un par de veces, pero no noté ningún cambio de rendimiento en los bucles normales DO.

En cuanto a la optimización, ¿qué tipo de paralelismo intentas usar? No me gusta mucho OpenMP, pero supongo que si lo utilizaste, deberías probar estos constructos primero.

+0

He utilizado OpenMP en el pasado y pude obtener una aceleración lineal para algunos de mis problemas, al menos en una pequeña cantidad de CPU. Esto parece necesitar el uso de DO en lugar de FORALL, lo que hace que esta construcción sea un poco inútil. Si no le gusta OpenMP, ¿qué otro método usaría para paralelizar bucles? – DaveP

+0

Bueno, prefiero MPI, es más escalable y me gusta más, ya que al utilizar OpenMP me metí en problemas para tareas paralelas más complejas sobre lo que es local para la región paralela y lo que no. La ventaja de MPI para mí es que es mucho más fácil pensar e implementar rutinas paralelas. Entonces, para mi cerebro, OpenMP solo es utilizable para la rutina más simple. – steabert

0

* Esto debería ser un comentario, no una respuesta, pero no cabe en esa pequeña caja, así que lo estoy poniendo aquí. No lo pongas en mi contra :-) De todos modos, para continuar un poco sobre el comentario de @ steabert sobre su respuesta. OpenMP y MPI son dos cosas diferentes; uno rara vez puede elegir entre los dos ya que es más dictado por su arquitectura que la elección personal. En cuanto a aprender conceptos de paralelismo, recomendaría OpenMP cualquier día; es más simple y uno fácilmente continúa la transición a MPI más adelante.

Pero eso no es lo que quería decir. Esto es: hace unos días, Intel anunció que comenzó a admitir Co-Arrays, una función de F2008 que anteriormente solo era compatible con g95. No tienen la intención de suprimir el g95, pero el hecho es que el compilador de Intel se usa más ampliamente para el código de producción, por lo que esta es definitivamente una línea interesante de desarrollo.También cambiaron algunas cosas en su Fortran Compiler Visual (el nombre, para empezar :-)

Más información después del enlace: http://software.intel.com/en-us/articles/intel-compilers/

+0

No estoy de acuerdo con "uno rara vez puede elegir entre los dos ya que está más dictado por su arquitectura que la elección personal", ya que creo que MPI es más independiente de la arquitectura que OpenMP. Para este último, está atascado con las arquitecturas de memoria compartida. – steabert

2

FORALL es una declaración de asignación enmascarada generalizada (como WHERE). No es una construcción de bucle.

Los compiladores pueden paralelizar FORALL/WHERE usando instrucciones SIMD (SSE2, SSE3, etc.) y es muy útil para obtener un poco de paralelismo de bajo nivel. Por supuesto, algunos compiladores más pobres no se molestan y simplemente serializan el código como un bucle.

OpenMP y MPI es más útil en un nivel más grueso de granularidad.

Cuestiones relacionadas