El nacimiento de los aceleradores 3D: cuando la GPU se convirtió en su propio mundo

¿Te fue útil?

Si alguna vez persiguió un ticket de “la GPU va lenta” durante tres horas solo para descubrir que el cuello de botella era un bucle de envío en CPU de un solo hilo, ya entiende la historia central:
el hardware gráfico no solo se volvió más rápido. Se volvió separado. Memoria distinta. Planificación distinta. Modos de fallo distintos. Una verdad distinta.

La GPU moderna no es un “acelerador” atornillado a un PC. Es un sistema completo con sus propias limitaciones y su propia gravedad operativa. Esa separación empezó en los años 1990,
cuando las tarjetas 3D dejaron de ser complementos simpáticos y empezaron a convertirse en mundos independientes que, por casualidad, se dedican a dibujar triángulos.

Del blitter al mundo: el momento en que los gráficos dejaron de ser “solo una tarjeta”

Los gráficos tempranos de PC eran fundamentalmente una historia de CPU. La “tarjeta gráfica” hacía salida de pantalla y cierta aceleración 2D—bit blits, trazado de líneas, quizá un cursor por hardware.
Pero la CPU gobernaba el pipeline. Si querías 3D, hacías las matemáticas en la CPU y empujabas píxeles al frame buffer como si estuvieras alimentando una impresora.

Luego los juegos se volvieron ambiciosos y la CPU se convirtió en un cuello de botella de programación. No porque las CPUs fueran “lentas” en abstracto, sino porque el renderizado 3D es una cinta transportadora:
transformaciones, iluminación, recorte, rasterización, texturizado, mezcla, pruebas de z-buffer. Haz eso a 30–60 fotogramas por segundo, para miles de triángulos, con múltiples texturas,
y tu CPU se convierte en un becario sobrecargado con una pila de formularios.

El avance no fue únicamente velocidad. Fue la especialización. Los aceleradores 3D tomaron partes específicas de ese pipeline e implementaron hardware para ellas—primero como bloques de función fija.
Estos bloques eran deterministas, masivamente paralelos (para su época) y optimizados en torno al ancho de banda y la localidad. No se generalizaban bien, pero no tenían que hacerlo. Tenían un trabajo.

Una vez que existieron esos bloques, desplazaron el centro de gravedad fuera de la CPU. Las necesidades de la GPU—ancho de banda de VRAM, complejidad del driver, envío de comandos por DMA, cambio de contexto—se convirtieron en
restricciones de ingeniería de primera clase. Aquí es donde “la GPU se convirtió en su propio mundo” deja de ser metáfora y empieza a ser tu experiencia en llamadas de soporte.

Broma #1: La GPU es como un compañero de trabajo extremadamente rápido que solo habla en lotes; si le haces una pregunta a la vez, los dos saldrán decepcionados.

Hechos históricos que importan operativamente

Aquí hay puntos históricos concretos que no son trivia: explican por qué las GPUs actuales se comportan como lo hacen, especialmente bajo carga y en producción.

  1. Tarjetas 3D de mediados de los 90 descargaban rasterización y mapeo de texturas, mientras las CPUs a menudo seguían manejando transformaciones de geometría. Esta división creó un patrón de “cuello de botella en el envío” que aún existe.
  2. 3dfx Voodoo (1996) popularizó el hardware 3D dedicado e introdujo a mucha gente el concepto de un pipeline 3D separado—a menudo como una segunda tarjeta, ni siquiera la pantalla primaria.
  3. Direct3D vs OpenGL no fue solo religión de APIs. Influyó en modelos de drivers, suposiciones de motores de juego y en cuán pronto las características se volvieron comunes—es decir, moldeó lo que los fabricantes optimizaron.
  4. AGP (finales de los 90) intentó proporcionar una vía amigable para gráficos hacia la memoria principal vía GART (Graphics Address Remapping Table). Fue una lección temprana en “la memoria compartida no es gratis”.
  5. Shaders programables (inicios de los 2000) cambiaron las GPUs de bloques de función fija a pipelines programables. Ese es el comienzo de la GPU como motor de cómputo paralelo general.
  6. Hardware T&L (transformación y iluminación) trasladó gran parte del trabajo de geometría a la GPU, reduciendo la carga en la CPU pero aumentando la complejidad de drivers y comandos.
  7. Arquitecturas de shader unificadas más tarde reemplazaron pipelines separados de vértices/píxeles, mejorando la utilización—pero también haciendo el rendimiento menos predecible sin perfilado.
  8. Multi-GPU (era SLI/CrossFire) enseñó una lección operativa desagradable: “más tarjetas” puede significar “más sincronización” y más rarezas en drivers, no escalado lineal.

El viejo pipeline 3D: por qué el hardware de función fija lo cambió todo

Para entender el nacimiento de los aceleradores 3D, debes comprender qué estaban acelerando: un pipeline que se descompone naturalmente en matemáticas repetibles.
La apuesta de diseño temprana era que estos pasos eran lo suficientemente estables como para cablearlos en hardware.

Bloques de función fija: predecibles, rápidos y extrañamente frágiles

Función fija significa que el silicio contiene unidades dedicadas: setup de triángulos, rasterización, muestreo de texturas, mezcla, pruebas de profundidad.
Tú proporcionas parámetros, hace la operación. Es rápido porque no hay sobrecarga de decodificar instrucciones y las rutas de datos están afinadas para la operación exacta.
También es frágil: cuando la industria quiere un nuevo modelo de iluminación o un combinador de texturas distinto, no puedes “parchar” el hardware.

Operativamente, las eras de función fija generaron un sabor específico de dolor: un único workaround en el driver podía decidir si tu motor funcionaba a 60 FPS o se bloqueaba al iniciarse.
Con hardware fijo, los fabricantes introducían capas de compatibilidad en los drivers, y el driver se convirtió en un emulador blando para características faltantes.
Ese legado nunca desapareció por completo; solo cambió de capa.

Envío de comandos: el inicio de “la GPU es asincrónica”

La CPU no “llama a la GPU” como una función. Construye buffers de comandos y los envía. La GPU los consume cuando puede.
Este modelo asincrónico empezó temprano porque era la única forma de mantener ocupadas tanto a la CPU como a la GPU.

Por eso la depuración de rendimiento es compleja. Tu CPU puede estar esperando una fence; tu GPU puede estar esperando datos; tu tiempo de frame puede estar dominado por una carga de texturas que olvidaste.
Si tratas a la GPU como un coprocesador síncrono, diagnosticarás mal el cuello de botella y “arreglarás” el componente equivocado.

El concepto clave: mantener los datos calientes cerca del lugar donde se usan

Texturas y buffers de frame son voraces en ancho de banda. Los aceleradores tempranos tomaron una decisión brusca y correcta: mantenerlos en VRAM local en la tarjeta.
Eso reduce la latencia y evita saturar el bus del sistema. También crea un nuevo recurso que gestionar: presión de VRAM, residencia, paginación y fragmentación.

VRAM, ancho de banda y por qué la GPU necesitó su propio reino de memoria

La GPU se convirtió en su propio mundo porque exigía su propia economía. Esa economía se mide en ancho de banda, no en GHz.
A la gente de CPU le encantan los clocks; a la gente de GPU le cuentan bytes por segundo y luego se quejan de todos modos.

Por qué existe la VRAM: rendimiento predecible vence a la astucia

Una GPU necesita leer texturas, escribir buffers de color, leer buffers de profundidad y hacerlo en paralelo. Ese patrón de acceso no es tipo CPU.
Las CPUs prosperan con cachés y predicción de ramas; las GPUs prosperan con transmisión y ocultación de latencia mediante paralelismo. La VRAM está diseñada para buses anchos y alto rendimiento.

Los intentos tempranos de “usar la RAM del sistema para texturas” (incluyendo texturizado AGP) parecían atractivos en papel. En la práctica, el bus se convirtió en cuello de botella,
y la variación de latencia provocó stutters. Enseñó a la industria una lección recurrente: los recursos compartidos son donde el rendimiento muere bajo concurrencia.

Residencia y paginación: el motor silencioso del stutter

Una vez que tienes VRAM separada, necesitas una política sobre qué vive allí. Cuando la VRAM está llena, algo debe ser expulsado.
Si la expulsión ocurre a mitad de frame, obtienes picos. Si ocurre a mitad de dibujo, obtienes stalls.
Las APIs modernas exponen un control más explícito (y más responsabilidad), pero el modo de falla es viejo: demasiadas texturas, demasiados render targets, memoria insuficiente.

Matemáticas de ancho de banda que cambian decisiones

A los ingenieros les encanta discutir “acotado por cómputo vs memoria”. Para gráficos, a menudo gana el ancho de banda. Si tu shader es simple pero tus texturas son grandes y tus render targets de alta resolución,
tu GPU puede aburrirse esperando memoria.

En términos operativos: si ves utilización de GPU baja mientras el tiempo de frame es alto, podrías estar limitado por memoria, por PCIe o por envío de comandos. La herramienta correcta es la medición, no la intuición.

AGP a PCIe: las guerras del bus y lo que nos enseñaron

El interconector del sistema define cuánta “separación de mundos” es posible. Cuando la GPU estaba en PCI, competía con todo lo demás. AGP le dio una vía más rápida y directa,
además de mecanismos como GART para mapear memoria del sistema. Luego PCIe llegó y convirtió a la GPU en un periférico de alto ancho de banda de primera clase con carriles escalables.

AGP: trato especial, modos de fallo especiales

AGP era “específico para gráficos”, lo que significó que tenía “bugs específicos para gráficos”. En la práctica, podías obtener inestabilidad que solo aparecía cuando un juego transmitía texturas agresivamente.
Ese tipo de fallo es catnip para los gerentes de incidentes porque parece corrupción aleatoria hasta que notas que se correlaciona con picos de ancho de banda.

PCIe: escalable, pero no mágico

PCIe te da carriles, velocidades de enlace e informes de errores. También te da nuevas formas de equivocarte: negociación a un ancho de enlace menor, eventos de retraining, errores corregidos que degradan silenciosamente el rendimiento
y resets de dispositivo bajo carga.

Si no monitoreas la salud de PCIe, estás tratando la GPU como una caja negra. Así es como terminas “optimizando shaders” para arreglar un riser defectuoso.

Drivers: donde las buenas ideas se encuentran con la física y los plazos

El driver es el tratado entre dos mundos. Traduce llamadas de API en buffers de comandos, gestiona memoria, programa trabajo, maneja estados de energía
y trata de permanecer estable mientras las apps hacen cosas creativas con comportamiento indefinido.

Por eso “funcionó en mi máquina” es especialmente inútil en el terreno de la GPU. La versión del driver, la versión del kernel, el firmware, el microcódigo e incluso la BIOS de la placa base pueden cambiar el comportamiento.
Puedes estar técnicamente en lo cierto y aun así provocar un crash.

Una cita para tener en una nota adhesiva

“La esperanza no es una estrategia.” — General Gordon R. Sullivan

Trata la fiabilidad de la GPU como tratas la fiabilidad del almacenamiento: asume que el camino feliz es una demo, no un contrato. Instrumenta, valida y fija versiones deliberadamente.

Las APIs moldearon el hardware

Direct3D y OpenGL no solo expusieron características; moldearon lo que los equipos de silicio priorizaron. Los pipelines de función fija mapearon limpiamente a las APIs tempranas.
Más tarde, los modelos de shader forzaron la programabilidad, y el hardware evolucionó para ejecutar pequeños programas a escala.

Conclusión operativa: si tu stack usa una abstracción de alto nivel (motor, runtime, framework), la abstracción puede estar filtrando viejas suposiciones sobre cómo funcionan las GPUs.
Cuando algo falla, lee los logs del driver y los mensajes del kernel primero, no la diapositiva de marketing.

Tres micro-historias corporativas del mundo real

Micro-historia #1: Un incidente causado por una suposición errónea

Una compañía de medios operaba una flota de transcodificación respaldada por GPU. El pipeline era mayormente estable: ingestión, decodificación, filtros, codificación, publicación.
Una mañana, la latencia de los trabajos se duplicó y la cola empezó a crecer. Los dashboards de CPU y GPU mostraban “bien”, que es la señal de que vas a desperdiciar tiempo.

La suposición del on-call fue: “Si la utilización de GPU es baja, la GPU no es el cuello de botella.” Así que escalaron nodos de CPU, aumentaron conteos de trabajadores y ajustaron pools de hilos.
La cola siguió creciendo. Los nodos GPU no mostraban banderas rojas obvias aparte de caídas ocasionales en el rendimiento PCIe—ignoradas porque nadie tenía una línea base.

La causa real fue una actualización de firmware en un subconjunto de servidores que negoció las GPUs a un ancho de enlace PCIe inferior tras reinicios en caliente.
Las GPUs no estaban “ocupadas” porque estaban famélicas: las transferencias DMA y las subidas de fotogramas eran más lentas, así que el pipeline pasaba más tiempo esperando copias.
El cómputo GPU parecía inactivo, pero el sistema estaba limitado por I/O.

La solución fue aburrida: inventario y aplicación forzada de parámetros de enlace PCIe, añadir alertas sobre cambios de ancho/velocidad, y fijar actualizaciones de firmware a ventanas de mantenimiento con validación.
La lección fue más aguda: baja utilización puede significar inanición, no margen. Trata “inactivo” como síntoma, no como veredicto.

Micro-historia #2: Una optimización que salió mal

Un equipo de visualización fintech tenía un dashboard de riesgo en tiempo real que renderizaba escenas 3D complejas—porque alguien decidió que los gráficos 2D no eran “inmersivos”.
Optimizaron mediante el batching agresivo de llamadas de dibujo y subiendo atlas de texturas más grandes con menos frecuencia. Los FPS mejoraron en laboratorio.

En producción, los usuarios reportaron congelamientos periódicos: la app corría fluida y luego se quedaba colgada medio segundo. Los gráficos de CPU mostraban picos.
El perfilado de GPU mostró largos stalls en intervalos impredecibles. El equipo culpó a la recolección de basura, luego a la red, luego a “Windows siendo Windows”, lo cual no es la causa raíz.

El problema real fue presión de VRAM y churn de residencia. Los atlas más grandes redujeron la frecuencia de subidas, pero cuando ocurrían eran masivas,
y el sistema ocasionalmente tenía que expulsar render targets para encajar. El driver realizó paginación implícita y sincronización en el peor momento posible.
La optimización aumentó la demanda máxima de memoria y convirtió los eventos de stall en raros pero catastróficos.

Lo arreglaron manteniendo los atlas por debajo de un umbral de residencia, dividiendo subidas en trozos más pequeños y presupuestando explícitamente la VRAM.
Los FPS promedio cayeron un poco; la latencia en la cola mejoró dramáticamente. Los usuarios prefieren 45 FPS consistentes sobre “a veces 90, a veces congelado”.

Micro-historia #3: Una práctica aburrida pero correcta que salvó el día

Una compañía SaaS ofrecía estaciones de trabajo virtuales con GPU. Nada glamuroso: CAD, edición de video, algunos notebooks ML.
Ejecutaban un proceso estricto de cambios para drivers y firmware de GPU: despliegue en etapas, nodos canary y rollback automático si aumentaban tasas de error.
No gustaba a los desarrolladores porque ralentizaba “tener las últimas mejoras de rendimiento”.

Un trimestre, una nueva versión de driver mejoró el rendimiento en varios benchmarks y solucionó un glitch gráfico conocido.
También introdujo un reset raro de GPU bajo una combinación específica de configuración multi-monitor y altas tasas de refresco.
El bug no apareció en pruebas sintéticas. Apareció en flujos de trabajo reales de clientes—porque la realidad siempre lo hace.

La pool canary lo detectó. Los logs del kernel mostraron errores estilo Xid de GPU y resets correlacionados con cambios en la configuración de pantalla.
El despliegue se detuvo en un pequeño porcentaje de nodos, los clientes se movieron automáticamente y el incidente se contuvo a un puñado de sesiones.

La práctica que los salvó no fue ingeniosa. Fue despliegue controlado más observabilidad.
La corrección aburrida es cómo evitas que las GPUs conviertan tu cola de soporte en arte performativo.

Tareas prácticas: comandos, salidas, significado y decisiones

No puedes depurar GPUs mirando un único porcentaje de utilización. Necesitas evidencia: velocidad de enlace, presión de memoria, errores de driver, envío por CPU y comportamiento térmico/energético.
A continuación hay tareas prácticas ejecutables en sistemas Linux comunes. Cada una incluye: el comando, salida de ejemplo, qué significa y qué decisión tomar.

1) Identificar la GPU y el driver en uso

cr0x@server:~$ lspci -nnk | grep -A3 -E "VGA|3D controller"
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA102 [GeForce RTX 3090] [10de:2204] (rev a1)
	Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:3897]
	Kernel driver in use: nvidia
	Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia

Significado: Confirma qué dispositivo y driver de kernel están activos. Si esperabas una GPU de centro de datos pero ves un modelo de consumo, ya estás depurando procurement, no rendimiento.

Decisión: Si el driver equivocado está en uso (p. ej., nouveau), corrige la selección del driver antes de tocar el código de la app.

2) Comprobar velocidad y ancho de enlace PCIe (crítico para “GPU inactiva pero lenta”)

cr0x@server:~$ sudo lspci -s 01:00.0 -vv | grep -E "LnkCap:|LnkSta:"
LnkCap:	Port #0, Speed 16GT/s, Width x16, ASPM L1, Exit Latency L1 <64us
LnkSta:	Speed 8GT/s (downgraded), Width x8 (downgraded)

Significado: La tarjeta soporta PCIe Gen4 x16 pero está funcionando en Gen3 x8. Eso puede reducir sustancialmente el ancho de banda de transferencia.

Decisión: Investigar ajustes de BIOS, risers, colocación en ranura o integridad de señal. No “optimices kernels” para compensar un enlace degradado.

3) Buscar errores PCIe corregidos y retraining de enlace

cr0x@server:~$ sudo dmesg -T | grep -iE "pcie|aer|corrected|link"
[Mon Jan 13 09:22:10 2026] pcieport 0000:00:01.0: AER: Corrected error received: 0000:01:00.0
[Mon Jan 13 09:22:10 2026] nvidia 0000:01:00.0: PCIe Bus Error: severity=Corrected, type=Physical Layer

Significado: Los errores corregidos aún pueden ser un olor de rendimiento e inestabilidad. Los problemas de capa física suelen implicar cableado/riser/ranura.

Decisión: Si los errores se correlacionan con carga, programa inspección de hardware y considera mover la GPU a otra ranura/nodo.

4) Observar utilización, memoria, potencia y relojes de la GPU (NVIDIA)

cr0x@server:~$ nvidia-smi
Tue Jan 13 09:25:01 2026
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.54.14              Driver Version: 550.54.14      CUDA Version: 12.4   |
|-----------------------------------------+----------------------+----------------------+
| GPU  Name                  Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf            Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                                         |                      |               MIG M. |
|=========================================+======================+======================|
|  0  NVIDIA RTX 3090                 Off | 00000000:01:00.0 Off |                  N/A |
| 30%   72C    P2              310W / 350W|  22500MiB / 24576MiB |     18%      Default |
+-----------------------------------------+----------------------+----------------------+

Significado: GPU-Util baja con uso de VRAM muy alto sugiere presión de memoria, sincronización o inanición por I/O—no necesariamente capacidad sobrante.

Decisión: Si la VRAM está casi llena, perfila asignaciones y reduce la residencia máxima (batches más pequeños, streaming, bajar resolución de render targets).

5) Ver estadísticas GPU en vivo para captar picos y throttling

cr0x@server:~$ nvidia-smi dmon -s pucvmt
# gpu   pwr gtemp mtemp   sm   mem   enc   dec  mclk  pclk  fb   bar1
# Idx     W     C     C    %     %     %     %   MHz   MHz  MB    MB
    0   315    74     -   22    55     0     0  9751  1695 22510  256

Significado: Potencia y relojes te dicen si estás siendo throttled. Si pclk cae mientras la temperatura sube, estás limitado térmicamente o por energía.

Decisión: Mejora la refrigeración, ajusta topes de potencia o reduce la carga sostenida. No persigas “micro-optimización” mientras estás con relojes bajos.

6) Comprobar resets de GPU o fallos de driver en logs

cr0x@server:~$ sudo journalctl -k -b | grep -iE "nvrm|xid|amdgpu|gpu fault|reset"
Jan 13 09:18:44 server kernel: NVRM: Xid (PCI:0000:01:00): 79, GPU has fallen off the bus.
Jan 13 09:18:44 server kernel: nvidia: probe of 0000:01:00.0 failed with error -1

Significado: “Fallen off the bus” sugiere un problema serio de PCIe/hardware/firmware, no un bug de aplicación.

Decisión: Trátalo como inestabilidad de hardware: vuelve a asentar, cambia de ranura, comprueba alimentación, actualiza firmware con cautela y pon en cuarentena el nodo.

7) Verificar grupos IOMMU y mapeo de virtualización (común en servidores GPU)

cr0x@server:~$ for d in /sys/kernel/iommu_groups/*/devices/*; do echo "$d"; done | grep -E "01:00.0|01:00.1"
/sys/kernel/iommu_groups/18/devices/0000:01:00.0
/sys/kernel/iommu_groups/18/devices/0000:01:00.1

Significado: La GPU y su función de audio están en el mismo grupo IOMMU. Eso es típico; el passthrough requiere aislamiento de grupo para seguridad y estabilidad.

Decisión: Si dispositivos inesperados comparten el grupo, ajusta configuraciones BIOS ACS o el layout de la placa antes de intentar passthrough limpio.

8) Medir cuellos de botella por envío en el lado CPU

cr0x@server:~$ pidof my-renderer
24817
cr0x@server:~$ sudo perf top -p 24817
Samples:  61K of event 'cpu-clock', 4000 Hz, Event count (approx.): 15250000000
Overhead  Shared Object      Symbol
  18.22%  libc.so.6          pthread_mutex_lock
  12.91%  my-renderer        SubmitCommandBuffer
   9.77%  libvulkan.so.1     vkQueueSubmit

Significado: Tiempo alto en locks y funciones de envío indica que la CPU es el limitador, no el rendimiento de shaders.

Decisión: Reduce la sobrecarga de envío: agrupa cambios de estado, usa grabación de comandos multihilo, evita locks por draw.

9) Confirmar efectos de huge pages / presión de memoria en cargas GPU

cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 6  0      0  81264  10240 512000    0    0     0    12 2310 5400 72 18  8  2  0
 8  0      0  62400   9984 498112    0    0     0    40 2600 6800 78 19  2  1  0

Significado: Muchos hilos en ejecución (r) y poco idle (id) sugiere contención de CPU. No es necesariamente malo, pero significa que “GPU lenta” puede ser inanición por CPU.

Decisión: Asignar afinidad de hilos, reducir sobre-suscripción de CPU o mover trabajos GPU a nodos con capacidad libre de CPU.

10) Comprobar límites de cgroup CPU (aplicaciones GPU en contenedores)

cr0x@server:~$ cat /sys/fs/cgroup/cpu.max
200000 100000

Significado: Este contenedor está limitado a 2 CPUs de tiempo (200ms por cada periodo de 100ms). Eso puede limitar el envío de comandos y la preparación de datos.

Decisión: Aumentar límites de CPU para cargas GPU; privar la CPU hace que la GPU parezca “subutilizada” y todos se confundan.

11) Inspeccionar sistema de archivos y espera de I/O al transmitir assets

cr0x@server:~$ iostat -xz 1 3
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          55.12    0.00    8.22   20.45    0.00   16.21

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s w_await aqu-sz  %util
nvme0n1         950.0  120000.0     0.0   0.00    7.20   126.32   110.0   24000.0   3.10   7.20   92.0

Significado: Alto iowait y alta utilización de NVMe significa que el streaming de assets puede bloquear pipelines de render/compute esperando datos.

Decisión: Precarga assets calientes, aumenta caché, mueve a almacenamiento más rápido o reestructura el streaming para evitar bloquear el hilo de render.

12) Rastrear procesos que consumen memoria a nivel de proceso (NVIDIA)

cr0x@server:~$ nvidia-smi pmon -c 1
# gpu        pid  type    sm   mem   enc   dec   command
# Idx           #   C/G     %     %     %     %   name
    0       24817     C    20    88     0     0   my-renderer
    0       25102     C     2     6     0     0   python

Significado: Un segundo proceso está usando VRAM. Eso puede desencadenar paginación y crear picos de latencia para la carga principal.

Decisión: Aplicar aislamiento (GPUs dedicadas por carga, políticas de scheduling o MIG donde esté disponible) y dejar de tratar la VRAM como “compartida por defecto”.

13) Validar nodos de dispositivo y permisos (fallo clásico en contenedores)

cr0x@server:~$ ls -l /dev/nvidia*
crw-rw-rw- 1 root root 195,   0 Jan 13 09:10 /dev/nvidia0
crw-rw-rw- 1 root root 195, 255 Jan 13 09:10 /dev/nvidiactl
crw-rw-rw- 1 root root 195, 254 Jan 13 09:10 /dev/nvidia-modeset

Significado: Los nodos de dispositivo existen. Si tu contenedor no puede verlos, es un problema de configuración del runtime, no “CUDA roto”.

Decisión: Arreglar passthrough de GPU del runtime del contenedor, reglas de dispositivos en cgroup o permisos udev.

14) Confirmar que las versiones de módulos del kernel coinciden con el stack instalado

cr0x@server:~$ modinfo nvidia | head
filename:       /lib/modules/6.5.0-18-generic/updates/dkms/nvidia.ko
version:        550.54.14
license:        NVIDIA
description:    NVIDIA kernel module

Significado: La versión del módulo del kernel debe alinearse con las herramientas de espacio de usuario. Desajustes pueden causar fallos sutiles o funciones faltantes.

Decisión: Si hay desajuste, reinstala el driver limpiamente y reinicia. No sigas parcheando un stack de drivers dividido.

15) Detectar señales de throttling térmico en sensores del sistema

cr0x@server:~$ sensors | sed -n '1,30p'
k10temp-pci-00c3
Adapter: PCI adapter
Tctl:         +88.8°C

nvme-pci-0100
Adapter: PCI adapter
Composite:    +73.9°C

Significado: Altas temperaturas de CPU y NVMe pueden afectar indirectamente cargas GPU (throttling de CPU, throttling de I/O), incluso si la GPU parece estar bien.

Decisión: Atender flujo de aire del chasis y curvas de ventiladores; un servidor con GPU es un aparato de gestión térmica que finge ser un ordenador.

Broma #2: Si no monitorizas el ancho de enlace PCIe, tu tuning de rendimiento es básicamente una danza interpretativa con gráficos.

Guía de diagnóstico rápido: qué comprobar primero/segundo/tercero

Cuando alguien dice “la GPU es el cuello de botella”, tu trabajo es evitar convertirte en un botón humano de reintento. Aquí tienes un playbook rápido que encuentra restricciones reales con rapidez.

Primero: ¿la plataforma está sana?

  • Estado de enlace PCIe: comprobar degradaciones. Si está degradado, detente y arregla hardware/firmware/ranurado.
  • Logs del kernel: buscar resets de GPU, errores AER, “fallen off the bus”, hangs.
  • Potencia y térmicos: verificar que los relojes sean estables bajo carga y que la energía no esté limitada inesperadamente.

Segundo: ¿la carga está dejando a la GPU hambrienta?

  • Envío por CPU: perfila vkQueueSubmit / glDraw* y locks.
  • Límites de contenedor: comprobar cgroup CPU y límites de memoria que estrangulan el trabajo de preparación.
  • Almacenamiento y streaming de assets: %iowait y %util de disco; un loader atascado puede parecer “stutter de GPU”.

Tercero: ¿la GPU está limitada por memoria o scheduling?

  • Presión de VRAM: VRAM casi llena + stutters = riesgo de churn de residencia.
  • Contención multi-tenant: otros procesos usando VRAM o tiempo de SM.
  • Throttling por potencia/térmico: relojes sostenidos bajos a pesar de la demanda.

Cuarto: Solo ahora, optimiza shaders/kernels

  • Mide si estás acotado por cómputo o por ancho de banda con herramientas de perfilado adecuadas en tu stack.
  • Reduce overdraw, optimiza patrones de acceso a memoria y ajusta tamaños de batch—después de verificar que el sistema no te está mintiendo.

Errores comunes: síntomas → causa raíz → solución

Estos son los modos de fallo que aparecen repetidamente cuando las GPUs “se convierten en su propio mundo” y los equipos olvidan que están operando dos sistemas, no uno.

1) Síntoma: utilización de GPU baja, pero tiempo de frame alto

Causa raíz: cuello de botella en envío por CPU, cuello de botella en transferencias PCIe o stalls por sincronización.

Solución: Perfila la CPU con perf, valida el estado del enlace PCIe e inspecciona fences/barriers. Agrupa trabajo; reduce la sobrecarga por draw; evita transferencias grandes por frame.

2) Síntoma: stutters periódicos cada pocos segundos

Causa raíz: expulsión/paginación de VRAM, picos en streaming de texturas o procesos en segundo plano que roban VRAM.

Solución: Reduce uso máximo de VRAM, prefetch, divide subidas en trozos, aplica aislamiento de GPU y establece presupuestos explícitos donde las APIs lo permiten.

3) Síntoma: resets aleatorios de GPU bajo carga

Causa raíz: problemas de alimentación, integridad de señal PCIe, bugs de driver o sobrecalentamiento.

Solución: Revisa dmesg/journal para firmas de reset, reduce el cap de potencia para probar estabilidad, vuelve a asentar o intercambiar hardware y controla despliegues de drivers.

4) Síntoma: rendimiento cae tras “actualizar drivers para velocidad”

Causa raíz: nuevo comportamiento de scheduling, diferente compilador de shaders, regresión en gestión de memoria.

Solución: Prueba A/B con canarios, fija versiones conocidas buenas y mantiene entornos reproducibles de build/runtime.

5) Síntoma: Funciona en bare metal, falla en contenedores

Causa raíz: nodos de dispositivo faltantes, hooks de runtime incorrectos, restricciones de dispositivo en cgroup o componentes userspace/kernel desajustados.

Solución: Valida la presencia y permisos de /dev/nvidia*, confirma versiones de driver coincidentes y revisa la configuración GPU del runtime del contenedor.

6) Síntoma: “Añadimos una segunda GPU y nada mejoró”

Causa raíz: la carga no es paralelizable, domina la sincronización, duplicación de VRAM o el envío por CPU se convierte en limitador.

Solución: Perfila el escalado. Si no puedes dividir el trabajo limpiamente, no compres complejidad. Prefiere una GPU más rápida o paralelismo de tareas bien diseñado.

7) Síntoma: caída repentina de rendimiento al aumentar resolución

Causa raíz: explosión de fill-rate/overdraw, saturación de ancho de banda de render target o agotamiento de VRAM.

Solución: Reduce overdraw, usa formatos más eficientes, ajusta AA/sombras y audita el conteo/tamaño de render targets.

Listas de verificación / plan paso a paso

Checklist A: Poner en marcha un nodo GPU como es debido

  1. Inventario de hardware: modelo GPU, capacidad PSU, plan de flujo de aire del chasis.
  2. Instalar y fijar versión del driver; registrar versión del kernel y versiones de firmware.
  3. Verificar ancho de enlace/velocidad PCIe al arrancar y después de reinicios en caliente.
  4. Ejecutar una prueba de carga sostenida y vigilar potencia, relojes, temperaturas y logs de errores.
  5. Configurar alertas sobre resets de GPU, errores AER y degradaciones de enlace.
  6. Establecer líneas base: utilización típica, uso de VRAM y rendimiento por workload.

Checklist B: Cuando el rendimiento está “misteriosamente” peor

  1. Confirmar que nada cambió: driver, kernel, firmware, BIOS, runtime de contenedores.
  2. Comprobar salud de la plataforma: estado del enlace PCIe y errores corregidos.
  3. Comprobar salud de la GPU: térmicos, throttling, resets.
  4. Comprobar limitaciones de CPU: perf, límites de cgroup, sobre-suscripción.
  5. Comprobar presión de VRAM y otros inquilinos de GPU.
  6. Comprobar almacenamiento/I/O si hay streaming involucrado.
  7. Solo entonces: afinar kernels/shaders y estrategia de batching.

Checklist C: Control de cambios en producción para stacks GPU

  1. Desplegar actualizaciones de drivers en canarios con workloads representativos.
  2. Recolectar logs del kernel y telemetría GPU durante la ventana canary.
  3. Definir triggers de rollback: resets, tasas de error, regresiones en latencia de cola.
  4. Desplegar en lotes; mantener una versión conocida buena disponible.
  5. Documentar expectativas de estado de enlace (Gen y ancho PCIe) por plataforma.

Preguntas frecuentes

1) ¿Qué era exactamente un “acelerador 3D” antes del término GPU?

Una tarjeta dedicada que descargaba partes del pipeline de renderizado 3D—a menudo rasterización, mapeo de texturas y mezcla—mientras la CPU aún hacía trabajo significativo de geometría.

2) ¿Por qué el hardware 3D temprano prefería diseños de función fija?

Porque entregaba rendimiento predecible por transistor. La industria conocía los pasos del pipeline y podía cablearlos en hardware para throughput y eficiencia de ancho de banda.
La programabilidad llegó cuando los bloques fijos no pudieron seguir el ritmo de técnicas de renderizado en evolución.

3) ¿Por qué la VRAM importa tanto comparada con la RAM del sistema?

La VRAM está diseñada para muy alto ancho de banda y interfaces anchas que coinciden con los patrones de acceso de la GPU. La RAM del sistema puede ser rápida, pero cruzar el bus añade latencia y contención,
y el patrón de demanda de la GPU castiga la imprevisibilidad.

4) Si la utilización de GPU es baja, ¿puedo asumir que la GPU no es el cuello de botella?

No. La baja utilización puede significar inanición (envío por CPU, transferencias PCIe, I/O), espera por sincronización o problemas de residencia de memoria.
Trata la utilización como una pista, no como una conclusión.

5) ¿Cuál es el cuello de botella “oculto” más común de GPU en producción?

Degradación del enlace PCIe o degradación de rendimiento relacionada con errores. Es común porque los equipos no toman una línea base del estado del enlace ni alertan sobre él.

6) ¿Por qué los drivers de GPU están tan implicados en incidentes?

Porque el driver se encarga de una enorme cantidad de política: gestión de memoria, scheduling, compilación y compatibilidad.
También es la capa que debe adaptar viejas suposiciones al nuevo hardware, a veces bajo presión de tiempo extrema.

7) ¿Cuál es un enfoque sensato para el uso multi-tenant de GPUs?

Prefiere aislamiento fuerte: GPUs dedicadas por carga, o particionado por hardware donde esté soportado. Si debes compartir, monitoriza uso por proceso,
establece cuotas/presupuestos y espera contención y picos de latencia en la cola a menos que la carga esté diseñada para compartir.

8) ¿Cómo distinguir rápidamente acotado por cómputo vs ancho de banda?

Empieza con telemetría: consumo de potencia y relojes (presión de cómputo) más uso de VRAM y throughput observado. Luego confirma con perfilado:
si aumentar reloj no ayuda pero reducir tráfico de memoria sí lo hace, probablemente estés limitado por ancho de banda.

9) ¿Qué cambió cuando llegaron los shaders programables?

La GPU dejó de ser un conjunto de bloques fijos y se convirtió en una máquina masivamente paralela programable. Eso desbloqueó nuevas características y también movió la complejidad:
compiladores, scheduling y portabilidad de rendimiento se convirtieron en preocupaciones operativas.

10) ¿Por qué “la GPU se convirtió en su propio mundo” importa para los SRE?

Porque ahora operas dos sistemas con modelos de recursos distintos: CPU/RAM/almacenamiento frente a GPU/VRAM/PCIe/driver/firmware.
Los incidentes suelen ocurrir en la frontera—donde las suposiciones son incorrectas y la visibilidad es pobre.

Siguientes pasos que realmente puedes hacer

Si ejecutas cargas GPU en producción—o estás por hacerlo—trata las GPUs como un subsistema de almacenamiento o una red: medible, falible y opinado.
El nacimiento de los aceleradores 3D enseñó a la industria que “gráficos” es un pipeline con su propia física. Las GPUs modernas solo hicieron ese pipeline programable y más fácil de malusar.

  1. Baselina el estado del enlace PCIe (velocidad y ancho) y alerta sobre cambios.
  2. Recolecta logs del kernel centralmente e indexa firmas de resets de GPU y errores AER.
  3. Presupuesta la VRAM por workload; trata la VRAM casi llena como un riesgo de fiabilidad, no como una medalla.
  4. Fija y canaryea actualizaciones de drivers; mide la latencia en cola, no solo el throughput medio.
  5. Perfila el envío por CPU antes de tocar kernels GPU—porque dejar hambrienta a la GPU es la forma más fácil de parecer “eficiente” en un dashboard.

Luego haz lo que la mayoría de equipos evita: escribe tus suposiciones sobre el mundo GPU (memoria, scheduling, costes de transferencia) y pruébalas. En producción, las suposiciones son incidentes sin archivar.

← Anterior
GPUs usadas tras minar: cómo verificar antes de pagar
Siguiente →
Debian 13: nftables + Docker — evita que las reglas automáticas te sorprendan (y arréglalo) (caso #39)

Deja un comentario