¿En qué paradigmas de programación debería invertir si quiero que mi código se ejecute en máquinas petascale en el futuro?


36

En una encuesta de los 500 principales, queda bastante claro que la industria tiende a un aumento exponencial en los núcleos de procesamiento . Las supercomputadoras más grandes usan MPI para la comunicación entre nodos, aunque no parece haber una tendencia clara para el paralelismo en el nodo, con el enfoque más simple (pero no necesariamente el más eficiente) para mapear un solo proceso MPI a cada núcleo, automático paralelización desde el compilador, OpenMP, pthreads, CUDA, Cilk y OpenCL.

Soy uno de un grupo de científicos que mantiene y desarrolla un código que tiene potencial para ser utilizado en algunas de las supercomputadoras más grandes del mundo. Suponiendo un tiempo de desarrollo limitado, ¿cómo me preparo para el futuro y aprovechar el rendimiento de la máquina más poderosa del mundo? ¿Qué suposiciones debo hacer sobre la arquitectura de interconexión de procesos? ¿Qué paradigmas van a sufrir cuando ingresemos a la era de los muchos puntajes? ¿Los idiomas de Partitioned Global Address Space estarán disponibles "en producción" en máquinas petascale?


55
No veo esta pregunta con el alcance adecuado. Según las preguntas frecuentes, "Sus preguntas deben tener un alcance razonable. Si puede imaginar un libro completo que responda a su pregunta, está preguntando demasiado". De hecho, cada conferencia de SuperComputing a la que he asistido tiene múltiples paneles sobre este tema y hay decenas a cientos de libros dedicados a diferentes paradigmas de programación
después del

relacionado tangencialmente: cs.stackexchange.com/questions/891/…
naught101

55
Bola de cristal no disponible, hojas de té estrelladas.
dmckee

Respuestas:


34

Perspectiva historica

Es realmente imposible decir cómo serán los nuevos paradigmas en el futuro, por ejemplo, una buena perspectiva histórica. Sugiero leer El ascenso y la caída de HPF de Ken Kennedy . Kennedy da cuenta de dos patrones emergentes, MPI versus un compilador inteligente, y detalla cómo MPI tuvo la cantidad correcta de primeros usuarios y flexibilidad para dominar. HPF finalmente solucionó sus problemas, pero ya era demasiado tarde.

En muchos sentidos, varios paradigmas, como PGAS y OpenMP, siguen la misma tendencia de HPF. Los primeros códigos no han sido lo suficientemente flexibles como para usarlos bien y dejaron mucho rendimiento sobre la mesa. Pero la promesa de no tener que escribir cada ápice del algoritmo paralelo es un objetivo atractivo. Por lo tanto, siempre se persigue la búsqueda de nuevos modelos.


Tendencias claras en hardware

Ahora, el éxito de MPI a menudo se ha citado como estrechamente vinculado a cómo modela el hardware en el que se ejecuta. Aproximadamente cada nodo tiene un número reducido de procesos y pasar los mensajes a un punto local a través de operaciones colectivas coordinadas se realiza fácilmente en el espacio del clúster. Debido a esto, no confío en nadie que ofrezca un paradigma que no siga de cerca las nuevas tendencias de hardware, de hecho, el trabajo de Vivak Sarakar me convenció de esta opinión .

De acuerdo con esto, aquí hay tres tendencias que claramente están avanzando en nuevas arquitecturas. Y déjenme ser claro, ahora hay doce arquitecturas diferentes que se comercializan en HPC. Esto es inferior a hace menos de 5 años con solo x86, por lo que los próximos días verán muchas oportunidades para usar hardware de maneras diferentes e interesantes

  • Fichas de propósito especial: piense en grandes unidades vectoriales como aceleradores (vista expuesta por Bill Dally de Nvidia)
  • Chips de baja potencia: grupos basados ​​en ARM (para acomodar los presupuestos de potencia)
  • Mosaico de chips: piense en el mosaico de chips con diferentes especificaciones (trabajo de Avant Argwal )

Modelos actuales

El modelo actual tiene en realidad 3 niveles de profundidad. Si bien hay muchos códigos que usan bien dos de estos niveles, no muchos han surgido usando los tres. Creo que para llegar al exascale primero hay que invertir en determinar si su código puede ejecutarse en los tres niveles. Este es probablemente el camino más seguro para iterar bien con las tendencias actuales.

Permítanme repetir los modelos y cómo deberán cambiar según las nuevas vistas de hardware predichas.

Repartido

Los jugadores en el nivel distribuido caen principalmente en los lenguajes MPI y PGAS. MPI es un claro ganador en este momento, pero los lenguajes PGAS como UPC y Chapel están avanzando en el espacio. Una buena indicación es el HPC Benchmark Challenge. Los lenguajes PGAS están dando implementaciones muy elegantes de los puntos de referencia.

El punto más interesante aquí es que si bien este modelo actualmente solo funciona a nivel de nodo, será un modelo importante dentro de un nodo para arquitecturas en mosaico. Una indicación es el chip Intel SCC, que actuó fundamentalmente como un sistema distribuido. El equipo de SCC creó su propia implementación de MPI y muchos equipos lograron portar bibliotecas comunitarias a esta arquitectura.

Pero para ser honesto, PGAS realmente tiene una buena historia para entrar en este espacio. ¿Realmente quieres programar el entrenudo MPI y luego tienes que hacer el mismo truco intranodo? Un gran problema con estas arquitecturas en mosaico es que tendrán diferentes velocidades de reloj en los chips y grandes diferencias en el ancho de banda de la memoria, por lo que los códigos de rendimiento deben tener esto en cuenta.

Memoria compartida en el nodo

Aquí vemos que MPI a menudo es "suficientemente bueno", pero los PThreads (y las bibliotecas derivadas de PThreads como Intel Parallel Building Blocks) y OpenMP todavía se usan con frecuencia. La opinión común es que habrá un momento en que haya suficientes subprocesos de memoria compartida para que el modelo de socket de MPI se descomponga para RPC o necesite un proceso más liviano ejecutándose en el núcleo. Ya puede ver las indicaciones de los sistemas IBM Bluegene que tienen problemas con la memoria compartida MPI.

Como comenta Matt, el mayor impulso de rendimiento para los códigos intensivos de cómputo es la vectorización del código de serie. Si bien muchas personas suponen que esto es cierto en los aceleradores, también es fundamental para las máquinas en el nodo. Creo que Westmere tiene una FPU de 4 de ancho, por lo que solo se puede obtener una cuarta parte de los flops sin vectorización.

Si bien no veo el OpenMP actual entrando bien en este espacio, hay un lugar para que los chips de baja potencia o de mosaico utilicen más hilos de luz. OpenMP tiene dificultades para describir cómo funciona el flujo de datos y, a medida que se usan más subprocesos, solo veo que esta tendencia se vuelve más exagerada, solo mire ejemplos de lo que uno tiene que hacer para obtener una captación previa adecuada con OpenMP.

Tanto OpenMP como PThreads en un nivel de curso suficiente pueden aprovechar la vectorización necesaria para obtener un buen porcentaje de pico, pero hacerlo requiere desglosar sus algoritmos de manera que la vectorización sea natural.

Coprocesador

Finalmente, la aparición del coprocesador (GPU, MIC, acumuladores de células) se ha establecido. Cada vez está más claro que ningún camino hacia exascale estará completo sin ellos. En SC11, cada contendiente del premio Bell los utilizó de manera muy efectiva para llegar a los petaflops bajos. Si bien CUDA y OpenCL han dominado el mercado actual, tengo esperanzas de que los compiladores de OpenACC y PGAS entren al espacio.

Ahora para llegar a exascale, una propuesta es acoplar los chips de baja potencia a muchos coprocesadores. Esto eliminará la capa intermedia de la pila actual y usará códigos que manejan problemas de decisión en el chip principal y eliminan el trabajo a los coprocesadores. Esto significa que para que el código funcione de manera bastante efectiva, una persona debe repensar los algoritmos en términos de núcleos (o codelets), es decir, fragmentos de nivel de instrucción sin ramificaciones. Hasta donde yo sé, una solución a esta evolución está bastante abierta.


Cómo afecta esto al desarrollador de la aplicación

Ahora para llegar a tu pregunta. Si desea protegerse de las complejidades inminentes de las máquinas exascale, debe hacer algunas cosas:

  • Desarrolle sus algoritmos para que se ajusten al menos a tres niveles de jerarquía paralela.
  • Diseñe sus algoritmos en términos de núcleos que se pueden mover entre la jerarquía.
  • Relaje su necesidad de procesos secuenciales, todos estos efectos sucederán de forma asincrónica porque la ejecución sincrónica simplemente no es posible.

Si quiere ser eficaz hoy, MPI + CUDA / OpenCL es lo suficientemente bueno, pero UPC está llegando allí, por lo que no es una mala idea tomarse unos días y aprenderlo. OpenMP te permite comenzar, pero genera problemas una vez que el código necesita ser refactorizado. PThreads requiere reescribir completamente su código a su estilo. Lo que hace que MPI + CUDA / OpenCL sea el mejor modelo actual.


Lo que no se discute aquí

Si bien toda esta charla sobre exascale es agradable, algo que no se discute realmente aquí es la entrada y salida de datos de las máquinas. Si bien ha habido muchos avances en los sistemas de memoria, no los vemos en el clúster de productos básicos (demasiado caro). Ahora que la computación con uso intensivo de datos se está convirtiendo en un foco principal de todas las conferencias de supercomputación, es probable que haya un mayor movimiento hacia el espacio de ancho de banda de memoria alta.

Esto lleva a la otra tendencia que podría suceder (si se involucran las agencias de financiación adecuadas). Las máquinas se volverán cada vez más especializadas para el tipo de computación requerida. Ya vemos máquinas "intensivas en datos" financiadas por la NSF, pero estas máquinas están en una pista diferente a la del Exascale Grand Challenge 2019.

Esto se hizo más largo de lo esperado, solicite referencias donde las necesite en los comentarios


2
Bien, pero ¿cómo podría ignorar la vectorización, que es el factor más importante para el rendimiento en el nodo?
Matt Knepley

Muy cierto (en realidad lo considero parte del nodo de cómputo especial, solo tuve una larga discusión con el Dr. Bandwidth sobre cómo los proveedores realmente sugieren que las personas apaguen las unidades vectoriales para los códigos de serie), también estoy ignorando los sistemas de memoria, y yo / o. Supongo que agregaré eso ahora.
aterrel

¿Los arreglos conjuntos en Fortran son más o menos equivalentes a UPC?
Ondřej Čertík

Por lo que puedo decir, son el mismo concepto, pero no he usado ninguna biblioteca ampliamente.
aterrel

En el sentido de que CAF y UPC son ambos PGAS, sí. Y tampoco es una biblioteca, por cierto. Hay mucha información en Internet para responder a esta pregunta con más detalle.
Jeff

8

Comencemos discutiendo una estrategia para el código intranodo (computación que no toca la interconexión), ya que creo que MPI es una buena opción para el código internodo. Creo que no tiene sentido hablar de nodos con menos de 100 núcleos, por lo que al menos una GPU o MIC actual.

Es un hecho que pthreads por sí solo no puede obtener el máximo rendimiento en cualquier chip moderno, ya que debe aprovechar la unidad de vector (cierto desde el primer Cray). En Intel y AMD puede usar intrínsecos, pero estos no son portátiles y, en mi opinión, son torpes. CUDA y OpenCL tienen una vectorización integrada en la biblioteca y facilitan el máximo rendimiento. Todo el nuevo hardware que conozco tiene este requisito de vector, por lo que cualquier solución debería tenerlo en cuenta. Para mí, CUDA / OpenCL es el camino actual a seguir.

A continuación, todas estas máquinas serán NUMA, que es más difícil de programar, pero creo que la estrategia del núcleo funciona. Divide el trabajo y los datos en pequeñas unidades. Probablemente se programarán automáticamente, como sucede actualmente en CUDA y OpenCL, pero puede especificar dependencias. Para los problemas que se ajustan al paradigma de transmisión, esta fragmentación también se puede hacer automáticamente. Intel TBB hace esto, pero prefiero el enfoque de biblioteca de nivel superior ejemplificado por Thrust y Cusp , que puede apuntar a CUDA o (pronto) TBB.


También creo que el enfoque de CUDA / OpenCL tiene un futuro brillante ... pero ¿cuál prevalecerá, CUDA u OpenCL? ¿El reciente fiasco de AMD dañará a OpenCL?
PhDP

2
Eventualmente habrá un estándar abierto que todos usarán. Probablemente sea OpenCL 2.0. Por ahora, CUDA está un poco por delante, pero puedo traducir fácilmente el 95% de mi código.
Matt Knepley

7

Intentaré una respuesta más corta que algunos de mis estimados colegas en este hilo ;-)

Mi mensaje a todos mis alumnos es siempre que el tiempo de desarrollador es más valioso que el tiempo de CPU. Eso significa que si tiene tiempo para convertir el 100% del código al 80% de eficiencia para ejecutarlo en máquinas grandes, utilizando un enfoque de alto nivel, entonces está mejor que cuando usa un bajo nivel que consume mucho tiempo enfoque que le brinda una eficiencia del 100% en el 20% de su código. Como consecuencia, soy un gran admirador de las bibliotecas de alto nivel. Mis favoritos en esta área son los bloques de creación de subprocesos (TBB), ya que me permite ver algoritmos en los bucles más externos y en un nivel alto. También puede hacer todo lo que quiera hacer con pthreads sin la dificultad de tener que lidiar con las funciones del sistema operativo, etc. No soy un fanático de los enfoques que miran los bucles más internos porque ese es el nivel incorrecto para explotar recursos paralelos intranodo: - entonces no hay OpenMP,

No puedo hablar con autoridad sobre OpenCL, CUDA, etc.


4

Las respuestas publicadas anteriormente son excelentes, pero se han centrado principalmente en la arquitectura de nodos, lo que creo que refleja el hecho de que MPI generalmente se considera suficiente como los modelos de programación de entrenudos en la mayoría de los casos y que es un paralelismo intranodo donde luchamos.

Aquí están mis intentos de responder dos preguntas que aún no han sido respondidas o respondidas de una manera relativamente limitada:

¿Qué suposiciones debo hacer sobre la arquitectura de interconexión de procesos?

Consideraré tres propiedades de las redes:

  1. estado latente,
  2. ancho de banda, y
  3. concurrencia

La latencia es inversamente proporcional a la frecuencia. Sabemos que la escala de frecuencia se ha estancado. Por lo tanto, se puede concluir que es poco probable que la latencia disminuya significativamente en el futuro. La latencia de envío y recepción de MPI en Blue Gene / Q es de alrededor de 2 us, lo que corresponde a 3200 ciclos. Más de la mitad de esa latencia es software, pero una buena parte del mismo es requerida por el estándar MPI; un ajuste extenso podría reducir la latencia a cerca de 1 us, particularmente si uno puede afirmar que los comodines MPI no se utilizarán.

En cualquier caso, la latencia de hardware para la inyección de paquetes en los sistemas Blue Gene y Cray es de alrededor de 1 us. En todo caso, aumentar la concurrencia a nivel de nodo hace que sea difícil mantener este número tan bajo, pero soy optimista de que los diseñadores de hardware encontrarán formas de mantener la latencia por debajo de 5 en el futuro previsible.

El ancho de banda de la red se incrementa trivialmente al aumentar el número de enlaces de red. Sin embargo, esto es solo una parte de la historia. Uno pone 1000 enlaces salientes en un nodo y no puede usarlos si los procesadores no pueden manejar la red con ancho de banda completo. Por ejemplo, algunas supercomputadoras tienen un cuello de botella en el bus (por ejemplo, HyperTransport) en lugar de en la red, en términos de ancho de banda de inyección.

No hay límites fundamentales para el ancho de banda de la red, solo prácticos. El ancho de banda cuesta dinero y energía. Los diseñadores de sistemas tendrán que tener en cuenta las compensaciones entre el ancho de banda de la red y otras partes de la máquina al desarrollar sistemas futuros. Muchos códigos no están limitados al ancho de banda de la red, por lo que parece poco probable que veamos máquinas con mucho más ancho de banda por conexión en el futuro. Sin embargo, el ancho de banda por nodo debe aumentar proporcionalmente a la potencia de cálculo, por lo que debe haber múltiples conexiones por nodo para escalar.

La tercera propiedad de las redes que a menudo se pasa por alto en los modelos formales es cuántos mensajes se pueden enviar una sola vez. Tener una red con 1 ns de latencia y / o 1 TB / s de ancho de banda que solo puede enviar 1 mensaje a la vez sería completamente inútil para la mayoría de los usos. Es importante poder enviar muchos mensajes de muchos hilos al mismo tiempo y que la red no colapse bajo contención. Los sistemas Cray y Blue Gene ahora alcanzan más de 1 MMPS (millones de mensajes por segundo). No recuerdo los números exactos, pero ambos pueden lograr una fracción significativa del ancho de banda máximo con mensajes pequeños. Una red ideal podría alcanzar el ancho de banda máximo con mensajes de cualquier tamaño, pero esto es imposible en la práctica debido al encabezado del paquete y los gastos generales de contabilidad relacionados. Sin embargo,

Esta es una respuesta incompleta e imperfecta. Otros pueden tratar de mejorarlo o sugerir cosas que debería mejorar.

¿Los idiomas de Partitioned Global Address Space estarán disponibles "en producción" en máquinas petascale?

Los sistemas Cray XE, XK y XC tienen un compilador UPC y CAF de calidad de producción. Los sistemas Blue Gene se pueden entregar con XLUPC y XLCAF, pero nadie lo solicita, por lo que no se entrega. PERCS tiene compiladores XLUPC y XLCAF de grado de producción, pero no instalaciones a gran escala que sean accesibles para la comunidad científica.

Los coarrays son parte de Fortran 2008, aunque las implementaciones en Intel y GNU Fortran aún no son de alta calidad. La implementación de Intel tiene fama de funcionar, pero también es bastante lenta (hay un documento en PGAS12 al respecto).

En cuanto al modelo de programación PGAS (dado que los modelos de programación, no los lenguajes de programación, son el tema de la pregunta original), la biblioteca Global Arrays es una aproximación razonable a la calidad de producción en muchos casos. Como tiempo de ejecución, no es tan robusto como MPI, pero MPI es bastante único en términos de la calidad de las implementaciones. La implementación ARMCI-MPI de ARMCI hace que las matrices globales sean mucho más estables, aunque más lentas en algunos casos.

Es relativamente fácil implementar construcciones de estilo PGAS de una manera de calidad de producción usando MPI-3 RMA. Si alguien publica una nueva pregunta sobre esto, me complacería responderla.


44
Puede publicar la pregunta sobre la implementación de construcciones de estilo PGAS en MPI-3 usted mismo (y responderla usted mismo), siempre que sea un problema real que haya enfrentado en el pasado (que supongo que es). Permitimos que los usuarios respondan sus propias publicaciones.
Geoff Oxberry

1
Esta es una de las preguntas más populares de scicomp, estoy feliz de tener la respuesta de Jeff presente aquí. EDITAR: veo lo que quieres decir allí @ GeoffOxberry: sí, debería publicar su propia pregunta y responderla :)
Aron Ahmadia

De acuerdo, trataré de reservar algo de tiempo para escribir una pregunta y respuesta "¿Cuál es la conexión entre PGAS y MPI-3 RMA" en la próxima semana o dos?
Jeff

3

Cantidades realmente masivas de núcleos también abren una perspectiva trivial pero sorprendentemente útil, solo para usarla para ejecutar muchas iteraciones de toda la simulación.

En la actualidad, una parte importante de la investigación computacional se reduce a escanear un espacio de parámetros, analizar un gran conjunto de condiciones iniciales o calcular una distribución de algún resultado de una manera de remuestreo; Todas esas tareas son vergonzosamente paralelas, por lo tanto, a prueba de Amdahl.


2

Sospecho que incluso las respuestas mejor pensadas para esta pregunta serán obsoletas en cinco o diez años. Dada la incertidumbre de los paradigmas de programación futuros, puede que no valga la pena dedicar una gran cantidad de tiempo a la optimización previa de su base de código.


1
Eso es demasiado fatalista: el futuro está aquí, hoy. La pregunta es sobre petascale, que es donde estamos hoy. Si no piensa cómo puede funcionar con los 100,000 procesadores de hoy, no progresará mucho con los 100,000,000 núcleos de mañana.
Wolfgang Bangerth

1

Estaba a punto de publicar esta respuesta a esta pregunta , pero se cerró como un duplicado de esta, así que aquí va:

Esto puede sonar un poco Solomónico, pero en mi experiencia, el futuro pertenece a enfoques híbridos en los que varios nodos multinúcleo de memoria compartida que ejecutan núcleos multiproceso están conectados a través de un paradigma de memoria distribuida como MPI.

Sin embargo, hay algunos problemas y no involucran el hardware en absoluto. En primer lugar, la mayoría de los programadores paralelos están fuertemente invertidos en códigos de tipo MPI y son muy reacios a ser los primeros en volver a implementar partes, o todas, de su base de código utilizando un nuevo paradigma. La falta de personas que utilizan enfoques de memoria compartida conduce a un progreso más lento en los algoritmos para esa área, lo que hace que cualquier inversión parezca aún más inútil.

Un segundo problema es que todos asocian paralelismo de memoria compartida con OpenMP . Si bien OpenMP es una buena forma rápida y sucia de resolver problemas pequeños y simples en un pequeño número de procesadores, es un modelo de programación absolutamente terrible para el paralelismo real de la memoria compartida. Aunque todos, en algún momento u otro, hemos aprendido una serie de paradigmas de programación paralelos simples y eficientes, por ejemplo, grupos de subprocesos o programadores , estos no son fáciles de implementar usando OpenMP y, francamente, este no es el tipo de paralelismo que OpenMP atrae a los programadores a usar.

En resumen, la barrera para pasar de una memoria puramente distribuida a un paradigma de memoria pura / parcialmente compartida es bastante alta. Si desea utilizar hilos de manera eficiente, debe olvidarse de OpenMP y gestionar los hilos y la concurrencia usted mismo (hola pthreads , adiós Fortran).

Pero, ¿por qué pasar a un enfoque híbrido? Bueno, aunque MPI se escala a miles de núcleos, el modelo subyacente es uno de sincronización sincronizada y patrones de comunicación estáticos. Esto es bueno para algunos problemas, por ejemplo, simulaciones de mil millones de partículas, pero subóptimo para problemas más difíciles o de grano más fino. Los paradigmas de memoria compartida hacen que el equilibrio dinámico de carga y / o la comunicación asíncrona sean mucho más fáciles, pero implica un gran esfuerzo de programación.


1
Estoy de acuerdo en que OpenMP es un paradigma terrible y está haciendo un gran daño a la comunidad. Pero al mismo tiempo, no es cierto que la alternativa sea administrar hilos, agrupaciones de hilos, colas de trabajo, etc. usted mismo; de hecho, hay bibliotecas muy buenas que hacen exactamente esto por usted. Los bloques de construcción Threading de Intel son los más notables. Lo hemos usado durante años bajo el capó en el trato II y funciona bastante bien.
Wolfgang Bangerth

Hmm, he estado buscando una aplicación o biblioteca robusta que use TBB para verificar que nuestra implementación de BG esté funcionando. Solo encontré cise.ufl.edu/research/sparse/SPQR anteriormente. ¿Hay alguna posibilidad de que intente ejecutar deal.II en BGP o BGQ usando wiki.alcf.anl.gov/parts/index.php/BlueTBB si proporciono la asignación?
Jeff

@WolfgangBangerth: Solo estoy provocando un aviso para ti, ya que creo que para eso estaba destinado el comentario de Jeff. Aunque no me importaría tener acceso a un BlueGene yo mismo;)
Pedro

@Jeff: estaría dispuesto a intentarlo, pero probablemente no pueda asignar una cantidad de tiempo terrible. No dude en ponerse en contacto conmigo sin conexión. (@Pedro: ¡Gracias por el aviso!)
Wolfgang Bangerth
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.