La guerra de las CPU y GPU

La guerra de las CPU y GPU

por

Hay ciertos cambios revolucionarios que se ven gatillados por el desarrollo tecnológico. Otros que se ven fuertemente influenciados por los costos de producción vs. el precio final. Lee a continuación cómo una apuesta por el más alto desarrollo concuerda con las mejores tasas de ganancia, pero se ve frenada por la forma actual de programar. Una interesante disputa de dos bandos: Performance extrema vs. programación eficiente.

Introducción y Contextualización del Problema

¿Por donde seguir? Esa parece ser la pregunta de fondo tras todo lo que les voy a contar hoy dia. Hasta ahora, el desarrollo de los últimos 20 años ha sido liderado por las CPUs en el sentido de poder, eficiencia y programabilidad. Los últimos años, con el ingreso de las GPUs poderosas a la cancha y los avances en programación para éstas demandados básicamente por las necesidades de los gamers que intentan ser satisfechas por los creadores de juegos que necesitan más poder de cálculo para desarrollar aplicaciones cada vez más poderosas (es un círculo, right?), la cosa está dejando de pelearse sólo en un área. Ahora llegamos al punto en que una opción debe ser tomada. Ambos approachs permiten poder, eficiencia pero de manera radicalmente distinta.

Para que vean por qué empezó a estar sobre el tapete este cuento, basta mencionar una afirmación de Intel en que dicen que hay un problema comparativo entre producir CPUs y producir GPUs: Los márgenes de ganancia de las CPUs están decreciendo, mientras los márgenes para las GPUs están aumentando. Ésto visto desde el punto de vista de un encargados de negocios (quien financia todo lo que se desarrollo por parte de una compañía) es, por decir lo menos, preocupante para las empresas de CPUs.

¿Qué es GPGPU?

GPGPU (Computación de Propósito General en la Unidad de Procesamiento Gráfico) ha sido tema de muchos artículos y muchas palabras en la actualidad, logrando por ejemplo grandes éxitos en el proyecto [email protected] entre otros. Básicamente, las razones de éste éxito son que GPGPU utiliza todo el poder de Punto Flotante que posee la GPU, que en la actualidad es un orden de magnitud (en bruto) que el de una CPU y además se vé beneficiado de los cambios en el diseño de la arquitectura de una GPU: Instrucciones de Punto flotante de 32 bits, Shaders complejos, Construcciones de programas en loop ramificados, etc. El problema para que esto se masifique, es decir, que tengamos muchísimos programas de propósito general corriendo en nuestras GPU’s es que la construcción de software es complejísima, o al menos radicalmente distinta que la construcción de software para CPU. Un punto clave para que esto prospere es CTM (Close-To-Metal, no el significado usual del foro) que es una interfaz de hardware que permite estrujar la tecnología de procesamiento secuencial 10 veces más que las API’s (Interfaz de Programación de Aplicaciones) por parte de ATI y CUDA (Configuración Unificada de Cálculo en el Dispositivo) por parte de Nvidia, que permite a los desarrolladores correr códigos en C en la GPU, de nuevo usando la tecnología de procesamiento secuencial. CUDA permite paralelizar en miles de threads (separación de procesos en 2 o más tareas ejecutadas en paralelo), paralelizar la caché de datos para obtener mayor intensidad aritmética en los speedups masivos (esto es, que tanto más rápido resulta ser un algoritmo en paralelo comparado a uno secuencial), usar librerías BLAS (Subprogramas de Álgebra Lineal Básica) y FFT (Transformadas de Fourier Rápidas), entre otros.

 

 

¿Cómo se trabaja y cuál es la diferencia entre una y otra forma de trabajo?

Hasta ahora, la evolución de las CPUs ha ido por las lineas del rendimiento del procesamiento en sí (que tan poderosas son las CPUs) y la de las GPUs hacia las lineas de procesamiento general (lo que les contaba más arriba en detalle). Al optimizar por la eficiencia energética, las CPUs adoptaron el camino del paralelismo explícito, con pros y contras. A usar VLIW (Sentencias de intrucciones muy largas) y Vectores ganan cuando hay una firme sincronización pero pierden cuando la data procesada sigue muchos caminos y al separar todo en Threads se invierte toda la cosa. Como el uso de ambas actualmente es inevitable para poder obtener una performance razonable, tienen que ajustar todo para que la eficiencia vectorial degrade lo menos posible la performance (mientras mayores sean los vectores la eficiencia baja) y mientras más cosas haya que comunicar, mas baja la eficiencia del Threading.

La información y la discusión que dejó como herencia el artículo de “Los 5 pilares de la paralelización” nos sirve muchísimo para entender este fenómeno. Piensen en el ejemplo del programa que intercambiaba los nombres de Pedro, Juan y Diego que se propuso anteriormente. El ataque de las CPUs es tratar de hacer los cambios de la manera más rápida posible uno tras otro con un código descrito en las funciones del ejemplo. Un ejemplo del uso de vectores que daría el enfoque de las GPUs podría ser guardar los nombres dentro de un vector y llamar a la dirección en que éste estaba siendo guardado (puntero) mediante una función resultante de una serie de permutaciones (cambié el 1 por el 2, luego el 2 por el 3, luego el 3 por el 1, etc.), haciendo posible llevar a cabo los tres procesos de manera simultáneas en tres threads diferentes pero con una función diferente para cada uno y con características más complejas entre uno y otro paso. Este es un ejemplo trivial, pero la pregunta de fondo es ¿Cómo escalarán ambos procedimientos al en vez de tener 3 personajes tengan millones o miles de millones?

Conclusiones y palabras al cierre

De manera sensata, lo único que se puede decir es que en el caso que un requerimiento de software específico sea programado para CPUs y GPUs actualmente las GPUs llevan la ventaja por un tema de capacidad de procesamiento (un orden de magnitud en escala de Flops) teniendo probablemente como consecuencia directa que el tiempo de desarrollo del software y las dificultades encontradas durante la programación sean muchísimo mayores, siendo inviables incluso en la gran mayoría de los proyectos. Las CPUs en cambio tienen un rendimiento razonable que va creciendo también a una tasa no despreciable (pero, menor que la de las GPUs) pero sus posibilidades de paralelización, clusterización, las nuevas tecnologías de intercomunicaciones entre nodos

En el futuro, con iniciativas como AMD Fusión que no solamente traerán de la mano eficiencia energética, miniaturización de componentes sino posibilidades de programación no exploradas hasta ahora al tener a la CPU y a la GPU en un mismo die, probablemente veamos que los desarrolladores que desarrollan para los desarrolladores de software (redundancias incluidas), es decir, quienes programan las APIs, Assemblers y etc., hagan de la experiencia de programar de manera vectorial para GPU menos tortuosa y comiencen a mezclarse seriamente con los programas en CPU, usando por decirlo así una combinación de ambos alcances para lograr el mejor resultado final posible.

La única lata del tema es para todos los que algo aprendimos a programar hace pocos años: parece que se viene una revolución tan grande como el paso hacia la programación de alto nivel, por allá en la década del 50′.

 

Comente este artículo