¿Por qué el código de paralelo de GPU es más complicado que el código de paralelo de CPU?

P: “¿Por qué el código de paralelo de GPU es más complicado que el código de paralelo de CPU?”

TL; DR: Porque la programación GPGPU no es tan madura y estandarizada. Sin embargo, esto se está volviendo menos cierto a medida que se desarrollan nuevas bibliotecas de paralelización.

Los SMP han existido desde los años 60, e históricamente se convirtieron en una arquitectura convencional para la paralelización. Casi todos los sistemas de hoy los usan y tienen API de subprocesos como subprocesos POSIX. Herramientas de paralelización como Boost, OpenMP construido sobre las API de hilo. Desde que se crearon estas herramientas, se desarrollaron aún más bibliotecas abstractas, lo que facilita aún más la paralelización. Si intenta programar usando subprocesos sin procesar, la paralelización de la CPU no parecerá tan fácil (aunque sugeriría que lo intente, de esta manera sabrá lo que está sucediendo bajo el capó).

Cuando se trata de GPU, históricamente se usaban principalmente para gráficos, de ahí su nombre. La paralelización manual no es necesaria si está realizando tareas gráficas comunes, solo puede usar bibliotecas como OpenGL. El uso de la programación de GPU de propósito general para otras tareas como HPC y la informática científica es una tendencia relativamente nueva. Las GPU no solo tienen una arquitectura de hardware diferente, sino que están diseñadas para la computación altamente orientada a SIMD. Esto significa que el paradigma de paralelización no es equivalente al de las CPU. Las GPU pueden realizar tareas específicas extremadamente rápido, pero no pueden realizar muchas otras tareas de programación comunes, especialmente aquellas con alta incertidumbre de ramificación. Es por eso que NVIDIA los llama aceleradores, en lugar de asesinos de CPU.

En 2011 tenía que ser doctorado y escribir un código CUDA complejo para acelerar la computación numérica, por ejemplo: cuda-convnet de Alex Krizhevsky. Hoy, puedes ser un estudiante de secundaria y escribir un programa acelerado por GPU más eficiente en 11 líneas de código Python. Hay muchas nuevas bibliotecas de aceleración de GPU en aumento que cubren más y más opciones de paralelización, por ejemplo: CuPY.

En resumen, las GPU no pueden hacer todas las tareas que las CPU pueden hacer, pero lo que pueden hacer, lo hacen mucho más rápido. Debido a sus diferencias de arquitectura, se necesita desarrollar nuevas abstracciones específicamente para la computación GPU. Hoy en día, hay muchas herramientas que puede usar para paralelizar / acelerar su código con facilidad, y en el futuro cada vez menos tareas requerirán una paralelización manual de bajo nivel.

Hablando en términos generales, las CPU deciden qué hacer en función de la hora. Programarlos es un ejercicio para presentar su solución como una secuencia de operaciones muy programada. Puede relajar el orden de ejecución marcando puntos en su programa / programa donde las operaciones funcionan igual independientemente, para que puedan extenderse a través de CPU paralelas. Básicamente, todavía está organizando una cadena de eventos: algunas operaciones pueden ir primero, mientras que otras deben venir después.

El programa dice qué hacer cuando , y la CPU (principalmente) se encarga de dónde encontrar los números.

Por el contrario, las GPU deciden qué hacer en función de los elementos de datos que se les han asignado. Programarlos es un ejercicio para convertir su solución en un sistema de coordenadas que particiona la entrada. Esto deja la mayor parte de la programación a la GPU, por lo que no tiene que rastrear el tiempo con cuidado, pero se produce a expensas de prestar mayor atención a cómo están organizados sus elementos de datos.

El programa dice qué hacer dónde , y la GPU (en su mayoría) se encarga de cuándo encontrar los números.

No estoy seguro de que una u otra forma de representar un problema sea más fácil que la otra, pero las GPU que tenemos actualmente no pueden hacer muchas cosas por sí mismas: su carga de trabajo se transmite, inicia y detiene mediante un programa que las controla. desde la CPU del sistema host. Creo que la razón esencial por la cual el código de paralelización de GPU es más complicado que el código de paralelización de CPU es que la paralelización de GPU es realmente paralelización de CPU y GPU . Te obliga a pensar de dos maneras sobre un programa, porque tienes que decidir qué partes de la computación se manejan mejor con qué tipo de maquinaria, y administrar la interfaz entre ellas.

Los detalles de la pregunta mencionan las molestias de instalar controladores, acoplar lenguajes y demás, pero estos están quizás más relacionados con la madurez de los estándares tecnológicos. En última instancia, podrían resolverse pagándole a alguien para que resuelva los aspectos técnicos antes de que especifique lo que hará su programa.

En cuanto a la paralelización de las GPU es realmente más complicada, diría que es porque es más difícil programar una máquina híbrida que una homogénea. No creo que se pueda simplificar mucho acortando la notación del código fuente.

En mi experiencia de uso de CUDA, la arquitectura asume que la GPU solo podría ejecutar la misma línea de código en todos los núcleos. Nvidia incluso aconseja evitar sucursales con operaciones de aritmética como multiplicar por uno y más cero, etc.

Estas son las características de la arquitectura que funcionan bien en la operación vectorizada pero funcionan mal en una operación que consiste en muchas ramas if-else. Esto es similar a las instrucciones SSE de Intel para CPU.

La flexibilidad en la programación de subprocesos para ejecutar diferentes códigos en diferentes núcleos viene con problemas como que el código debe considerar la seguridad de los subprocesos / atomicidad / comparar e intercambiar y el rendimiento al compartir la línea de caché entre los núcleos.

La razón es doble:

  1. El modelo de programación en GPU es diferente, por ejemplo, mencionaste CUDA. Esto no siempre es más difícil per se, pero definitivamente es diferente y no se enseña tanto en la universidad.
  2. Probablemente, la “paralelización simple en 7 líneas de código de CPU” de la que habla es el compilador que autovectoriza sus bucles o algo por el estilo. Esto es mucho más fácil porque si tiene código pesado de ramificación después de este segmento paralelo de código, su CPU lo manejará bien, pero su GPU no lo hará y, por lo tanto, necesita un modelo de programación diferente (es decir, mencionó CUDA).

Debido a que GPU es una parte adicional, cuando agrega algo tiene que configurarlo. Cuando instalas algo tienes que configurarlo. Simple es eso.

More Interesting

¿Dónde puedo aprender el aprendizaje automático desde cero en C ++?

¿Dónde puedo obtener más información sobre la persona en el MIT Media Lab que está trabajando para eliminar el sesgo en el aprendizaje automático?

¿Se pueden usar datos generados por simulación por computadora para algoritmos de aprendizaje automático?

¿Qué aplicaciones iOS usan TensorFlow del lado del cliente?

¿Qué es una explicación simplificada y una prueba del lema de Johnson-Lindenstrauss?

¿Cuál es la forma correcta de calcular la similitud de coseno entre una consulta y un documento? Cuando calculo la magnitud del documento, ¿sumo los cuadrados de todos los términos del documento o solo los de la consulta?

¿Cuál es el asistente virtual personal más avanzado?

Estamos viendo el comienzo de las máquinas que pueden codificar. ¿Aprender un lenguaje de programación aún sería útil en la carrera de ML?

Cómo usar un árbol de decisión para clasificar un conjunto de datos no balanceado

Cómo elegir el conjunto de validación para poder representar mejor el conjunto de prueba

¿Qué es una explicación intuitiva de la iteración de valores en el aprendizaje por refuerzo (RL)?

¿Es el atributo central del reconocimiento de patrones genios?

¿Por qué es mejor usar la función Softmax que la función sigmoidea?

¿Hay alguna forma de implementar TSVM usando bibliotecas SVM?

¿Cuáles son algunas buenas implementaciones para modelos gráficos probabilísticos? En particular, quiero poder crear y visualizar redes de creencias y aplicar varios algoritmos como la eliminación de variables y otros algoritmos de aproximación.