ArchiTecnologia

Aprendizaje abierto. Conocimiento libre.

ArchiTecnologia
HardwareProgramación

¿Es posible escribir un sistema operativo específico para GPU?

A veces me hacen preguntas extrañas, pero que son interesantes si las analizas a fondo. Una de esas preguntas es si se podría escribir un sistema operativo para que se ejecutase directamente sobre una GPU, y así aprovechar las capacidades de estos chips en vez de usar una CPU.

Intentaré explicar de la mejor forma posible la respuesta…

Introducción al funcionamiento CPU-GPU

Antes de nada deberías tener claro cómo funciona una CPU junto con una GPU en un sistema. La primera cosa que debes saber es que la CPU es la que controla todo, siendo la GPU un periférico más conectado mediante un bus (con líneas de direcciones para acceso a memoria, señales de interrupción, alimentación, reloj, etc.). Algunos sistemas actuales han integrado CPU y GPU en un mismo empaquetado (GPUs integradas), e incluso en un mismo chip (APUs), pero eso no cambia la forma de funcionar a groso modo.

En el lado del software, la CPU ejecutará el controlador diseñado para comunicarse con el periférico, en este caso la GPU. Así le podrá enviar comandos y recibir respuestas. Es decir, podrá transferir datos e instrucciones de programa para que la GPU pueda ejecutarlas. Una vez termina, la GPU avisa a la CPU de que ha completado la ejecución y así la CPU puede extraer el dato obtenido. Por tanto, cuando se ejecuta un software gráfico, como un videojuego, es la CPU la que lo procesa y luego envía las tareas a la GPU a través del bus. En ningún momento es la GPU la que toma la iniciativa, es decir, es un hardware dependiente de la CPU.

Por ejemplo, imagina que deseas dibujar una figura en pantalla usando la API gráfica Vulkan u OpenGL. Para realizar esa tarea simple intervendrán:

  • Hardware:
    • CPU
    • GPU
    • Memoria primaria (RAM)
    • Memoria secundaria (SSD/HDD)
    • Monitor
  • Software:
    • Sistema operativo (kernel)
    • API gráfica como OpenGL o Vulkan…
    • Driver o controlador de la GPU

Cuando un programador quiere dibujar una figura, primero generará el código fuente para realizar el dibujo usando alguna de las APIs gráficas disponibles. Cuando ese software esté compilado, la CPU comenzará su ejecución, encargándose de todo, excepto de algunos «encargos» que hará a la GPU gracias a un mapeo de memoria que permite a la CPU acceder a la memoria de la GPU.

Adaptar código genérico a una GPU

OpenCL, modelo memoria

Explicado de un modo tosco y acelerado, recuerda que una GPU trabaja de forma vectorial y es una arquitectura circulante (streaming). Es decir, en vez de depender del acceso a memoria como la CPU, en la circulante se genera un flujo de datos y lo que se «mueve» son los operandos. Así se introducen los datos en la GPU y se hace que las instrucciones «decidan» cómo se moverán esos datos a través de la microarquitectura.

Dicho de otro modo, todos los núcleos de la GPU ejecutan la misma instrucción al mismo tiempo, pero operan con diferentes datos (véase SIMD – Taxonomía de Flynn). Además, una GPU es como una CPU pero para un uso muy específico. Con una arquitectura altamente paralela, pero mucho más simple en muchos aspectos y más lentos.

Cuando se usa la GPU para propósito general (GPGPU), se tiene en cuenta que hay varios tipos de procesadores programables. Por ejemplo, para vértices y para colores. Ambos trabajan con vectores de cuatro datos (x, y, z, w) y (r, g, b, a). En estos casos, se deberá adaptar los datos de entrada (los que la CPU ha colocado en la memoria principal) para las necesidades y arquitectura de la GPU. Es decir, los datos a procesar por la GPU se tratan como si fuesen problemas de geometría espacial, como una lista de vértices y colores.

Además, el código del programa debe adaptarse bien para que sea procesado por la GPU. Por ejemplo, las constantes del código se deben almacenar en un banco de registros junto al procesador de vértices para que puedan ser usados, mientras que las variables se pueden presentar como atributos de los vértices y sus valores deben ser pre-tratados por la CPU para adaptarlos.

Los arrays de la memoria principal se adaptarán como mapas de texturas para portarlos a la memoria de vídeo (VRAM). Los bucles serán tratados como una lista de vértices o tendrán que pasar n veces por el renderizador para su correcta ejecución. Las sentencias condicionales también serían tratadas o adaptadas para actuar como operaciones de clipping, máscara de colores, etc.

Y los operadores se tratarían como operaciones de textura si son de tipo aritmético de coma flotante; como funciones de mezclado (blending) si son operaciones de reducción; y como operaciones de sombreado si son complejas… Además, los operadores lógicos, operadores a nivel de bits, accesos directos a registros, stack, head, … se debería emular usando algunos trucos en el código, ya que en una GPU no tienen cabida ese tipo de características.

Una vez los datos corren el cauce de la GPU, serán aceptados por los procesadores de vértices. Pero habría que evitar que cada vértice se transforme en más de un píxel (más de un dato de salida), lo que generaría un error. Para eso se hace uso de ciertas llamadas definidas en la API OpenGL.

El clipping y culling serviría tras la salida de los datos de los procesadores de vértices para sentencias condicionales. Luego vendrían las etapas de interpolación y rasterización, otro punto delicado si no quieres que alteren el resultado. Después vendría el procesador de píxeles, donde se procesan datos siguiendo un modelo SIMD. Y una vez sale el resultado se almacena en el frame buffer de la VRAM, representados como si fuesen píxeles.

Desde ahí se puede recuperar el resultado que vuelve a la RAM principal para saltar de nuevo a la CPU

¿Se podría entonces adaptar un SO a una GPU?

Todo lo anterior es teniendo en cuenta los controladores específicos para una GPGPU, y el uso de APIs como OpenCL/CUDA, además de tomar ayuda de la CPU. Es decir, usar simplemente la GPU como un «acelerador» de propósito general. Pero ¿y si queremos usarla como el procesador principal? Veamos los problemas…

En principio…

En principio (y solo en principio) puedes pensar que eso es imposible. Que no hay ensambladores para GPU, que la ISA real de algunas GPUs, como NVIDIA, es un secreto comercial, aunque algunos muestren especificaciones como AMD. Por tanto, se comienza con la falta de muchas piezas clave para comenzar a diseñar un kernel.

Por otro lado, la GPU no suele tener niveles de anillo como lo tiene una CPU, es decir, no podrías separar código privilegiado (espacio kernel) de no privilegiado (espacio de usuario). Esto sería un serio problema para la seguridad, que volvería a como estaba hace décadas.

Olvida la predicción de saltos en una GPU, tampoco la tienen. Son muchas unidades de procesamiento juntas, pero muy sencillas, como lo eran las CPUs de hace años. Esto no es un impedimento para no poder ejecutar software, de hecho las CPUs antiguas tampoco tenían predicción de saltos, pero sí que es una diferencia significativa.

La GPU tampoco tiene interrupciones de hardware, otro problema. ¿Cómo se gestionarán cosas como la programación dinámica, conmutación de tareas E/S, etc.? Y a eso le agregas que no tiene memoria virtual robusta, por lo que cada proceso en memoria podría ver el espacio asignado de los demás. ¡Otro serio problema de seguridad!

Además, cuando compruebas lo que es una GPU, te das cuenta que son básicamente muchas «CPUs» muy muy simples para trabajar en paralelo. Por tanto, habría que adaptar el SO para que pueda aprovechar todo eso, más complicado aún teniendo en cuenta que el microcódigo de una GPU está orientado a operaciones gráficas. Habría que adaptar las operaciones gráficas a las genéricas…

Por otro lado, se debería conseguir que la GPU acceda al espacio de almacenamiento y red. Y arreglar otras tantas cosas para ejecutar el sistema operativo sobre ella. ¿Conclusión? En principio no habría motivo para ejecutar un SO sobre una GPU, aunque sí que se puede sacar beneficio de usar una GPGPU para ejecutar cierto código para alto rendimiento… Es decir, una GPU no reemplaza a una CPU, simplemente puede usarse como un acelerador.

…pero sí que ¿es posible?

Dawn OS GPU

Pero algunos proyectos como este te pueden llevar a pensar que sí es posible. Me refiero al proyecto creado por Geri. Se llama Dawn OS y es un sistema operativo creado para funcionar sobre una GPU (testado en GPUs AMD).

Dawn OS se puede ejecutar en una GPU, salvando todos esos inconvenientes. Lo hace en la arquitectura SUBLEQ, que no usa un conjunto de instrucciones tradicional. Un tipo de OISC (One Instruction Set Computer), es decir, una especie de RISC extremo que solo usa una instrucción, en este caso SUBLEQ (Subtract and Branch if Less than or equal to Zero).

Es de 64-bit, big-endian, aunque permite varios modos de CPU, no tiene DMA, ni interrupciones, ni usa MMU o paginación de memoria. Ha sido diseñado para que tenga una alta eficiencia energética. Además, con él podrás aprender muchas cosas, e incluso tratar de ejecutarlo en alguna FPGA de una forma mucho más fácil que cualquier otra plataforma.

Es un sistema operativo moderno, con interfaz gráfica, multitarea, compatible con SMP, y con las funciones siguientes:

  • Soporte para ratón y teclado
  • Teclado virtual en pantalla
  • Multitáctil
  • E/S de sonido de 64-bit en 8 canales
  • Admite hasta 4 joysticks con force-feedback, y 16 cámaras RGB
  • Salida de gráficos RGBA hasta 32b-bit
  • Capacidad de red
  • Soporte para conexión en caliente de unidad de disco (hasta 100)
  • Tiene paquetes de software básicos preinstalados para texto, dibujo, reproductor de sonido, juegos simples, compilador C, etc.
  • Funciones de batería y ahorro de energía
  • Admite código ASCII, Unicode, y UTF8

… o tal vez no (conclusión)

Por el momento se puede ejecutar en un emulador SUBLEQ para OpenCL 1.0 en un sistema operativo host (existe un binario pre-compilador para Linux si lo quieres probar). Es decir, no puede ser iniciado directamente. Por tanto, no se puede correr «bare-metal» sobre una GPU. ¿Por qué? Volvemos habría que volver a repasar las cuestiones de este apartado «En principio…«.

Isaac

Apasionado de la computación y la tecnología en general. Siempre intentando desaprender para apreHender.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Si continuas utilizando este sitio aceptas el uso de cookies. más información

Los ajustes de cookies de esta web están configurados para "permitir cookies" y así ofrecerte la mejor experiencia de navegación posible. Si sigues utilizando esta web sin cambiar tus ajustes de cookies o haces clic en "Aceptar" estarás dando tu consentimiento a esto.

Cerrar