Felicitaciones por CUDA

Hola de nuevo. Yo soy Simón Sánchez y hoy te voy a contar sobre Felicitaciones por CUDA

Han pasado casi tres años desde que la computación GPU se unió a HPC con la introducción de la API CUDA de NVIDIA en septiembre de 2007. Desde entonces, la adopción de la tecnología ha avanzado a un ritmo sorprendentemente fuerte y constante. Muchas organizaciones que comenzaron pequeños proyectos piloto hace uno o dos años se han movido a la implementación empresarial, y las máquinas aceleradas por GPU ahora están representadas en la lista TOP500 comenzando en la posición dos. La adopción relativamente rápida de CUDA por una comunidad que no es conocida por la rápida adopción de nada es un signo digno de mención. Contrariamente a la opinión generalizada de que la computación con GPU es más difícil, creo que su éxito hasta ahora indica que no es más complicado que una buena programación de CPU. También expresa de manera más clara y concisa el paralelismo de una amplia clase de problemas que conducen a un código más fácil de mantener, más escalable y mejor posicionado para mapear futuras arquitecturas de múltiples núcleos.

El crecimiento continuo de CUDA contrasta fuertemente con el cementerio de idiomas abandonados introducidos en el mercado de HPC durante los últimos 20-25 años. Su éxito se puede atribuir en gran medida a i) el apoyo de un importante patrocinador corporativo sobre un consorcio, ii) la madurez de sus compiladores iii) la adherencia a una sintaxis C fácilmente reconocible por los desarrolladores, y iv) una característica más efímera que se puede describir mejor como elegancia o sencillez. Los físicos y matemáticos a menudo usan la palabra «elegante» como un gran cumplido para describir soluciones o ecuaciones particularmente atractivas que representan claramente fenómenos físicos complejos; donde el lenguaje de las matemáticas de manera sucinta y … bueno … describe y captura con elegancia la simetría y la física. CUDA es una elegante solución al problema de representar el paralelismo en algoritmos, no todos los algoritmos, pero lo suficiente como para ser importante. Parece resonar un poco con la forma en que pensamos y codificamos, lo que permite una expresión más simple y natural del paralelismo más allá del nivel de actividad.

Los desarrolladores de HPC que escriben código paralelo en la actualidad tienen dos opciones comerciales i) plataformas multinúcleo tradicionales creadas en CPU de Intel / AMD y ii) plataformas aceleradas por GPGPU de NVIDIA y AMD / ATI. El desarrollo de código paralelo escalable y de rendimiento para arquitecturas multinúcleo aún no es trivial e implica un modelo de programación multinivel que incluye paralelismo entre nodos gestionado con MPI, paralelismo intranodo con MPI, OpenMP o pthreads y paralelismo a nivel de registro expresado a través de Transmisión de instrucciones SIMD (SSE). La expresión de paralelismo en este modelo multinivel es a menudo detallada y confusa, oscureciendo el algoritmo subyacente. El desarrollador a menudo se queda con la sensación de estar en paralelo.

El modelo de programación CUDA presenta un enfoque diferente, algo refrescante, de la expresión del paralelismo. El trío MPI, OpenMP y SSE han evolucionado de un mundo centrado en el procesamiento en serie. CUDA, por otro lado, proviene de un mundo decididamente paralelo, donde miles de hilos simultáneos se manejan como la norma. El modelo de programación obliga al desarrollador a identificar el nivel irreductible de paralelismo en su problema. En un mundo que se mueve rápidamente hacia muchos núcleos, no hacia varios núcleos, esta parece ser una forma mejor, más intuitiva y extensible de pensar sobre nuestros problemas.

CUDA es un lenguaje de programación con construcciones diseñadas para la expresión natural del paralelismo a nivel de datos. No es difícil comprender la expresividad en los idiomas y la idea de que algunos conceptos se expresan más fácilmente en idiomas específicos. Los informáticos hacen esto todo el tiempo mientras crean estructuras óptimas para representar sus datos. Los pares de bases de ADN, por ejemplo, se expresan de forma clara y compacta como una secuencia de campos de datos de 2 bits mucho mejor que una simple representación ASCII. A nuestro estudiante de intercambio italiano le gustaba enfatizar la gran superioridad del italiano sobre el inglés para temas apasionantes.

De manera similar, hemos encontrado en muchos casos que la expresión del paralelismo algorítmico en CUDA en campos tan diversos como petróleo y gas, bioinformática y finanzas es más elegante, compacta y legible que el código de CPU optimizado equivalente, preservando y presentando más claramente el algoritmo subyacente. En un proyecto reciente, redujimos 3500 líneas de código C altamente optimizado a un núcleo CUDA de aproximadamente 800 líneas. Optimized C estaba plagado de ensamblajes Online, macros SSE, bucles desenrollados y casos especiales, lo que dificultaba la lectura, la extracción de significado algorítmico y la extensión en el futuro. En comparación, el código CUDA era más limpio y legible. Eventualmente será más fácil de mantener.

El procesamiento paralelo de materia prima comenzó como una forma de dividir las tareas grandes en varios procesadores conectados de manera flexible. Los modelos de programación apoyan la idea de dividir los problemas en varias piezas más pequeñas de trabajo equivalente. Con el tiempo, estos procesadores se han acercado entre sí en términos de latencia y ancho de banda, primero como nodos multiprocesador del sistema operativo único y luego como componentes del procesador multinúcleo de esos nodos. De cara al futuro, solo vemos más núcleos por chip y más chips por nodo.

A pesar de que nuestros núcleos de cómputo están más estrechamente acoplados, nuestra visión de ellos sigue estando en gran medida desde una mentalidad de tareas paralelas de arriba hacia abajo, es decir, tomar un gran problema, dividirlo en muchos trozos pequeños, distribuirlo a los elementos de cómputo. y lidiar con ello con la comunicación. En este enfoque de arriba hacia abajo, debemos descubrir un nuevo paralelismo en cada nivel, un paralelismo a nivel de dominio para MPI, un nivel «for-loop» para OpenMP y un paralelismo a nivel de datos para SSE. Lo intrigante de CUDA es que adopta un punto de vista de abajo hacia arriba, identificando la unidad atómica de paralelismo e incorporándola a una estructura jerárquica, como thread :: warp :: block :: grid.

La contribución duradera de la computación GPU a HPC podría ser un modelo de programación que nos aleje del enfoque actual de arriba hacia abajo, multinivel y tareas paralelas, en lugar de difundir una alternativa de abajo hacia arriba más escalable y paralela a los datos. No es justo para todos los problemas, pero para aquellos que encajan bien con ellos, como las plantillas de diferencias finitas y la dinámica molecular, entre muchos otros, proporciona un lenguaje más limpio y natural para expresar el paralelismo. Debe reconocerse que la expresión más simple y limpia para estas aplicaciones en el código es un motor principal para una adopción relativamente rápida por parte de los profesionales académicos y empresariales. Además, no hay ninguna razón inherente por la que el escalado deba detenerse a nivel de red o dispositivo. Uno puede imaginar fácilmente una generalización de CUDA en arquitecturas futuras que abstraiga una o más capas por encima de la cuadrícula para realizar una implementación de múltiples dispositivos, agregando de manera efectiva la memoria global en un rango contiguo; algún tipo de enfoque GPU / NUMA. Si se puede hacer esto, la computación GPU habrá dado un gran salto hacia la resolución de un problema clave en la computación paralela al reducir el modelo de programación de tres niveles a un nivel para una solución más simple y elegante.

Acerca de

Se puede contactar al Dr. Natoli en [email protected].

Deberías compartir en en tu Twitter y Facebook para que tus colegas lo sepan

??? ? ? ???

Comparte