nbd-vram - Herramienta para usar la VRAM de una GPU NVIDIA como espacio de swap en Linux
(github.com/c0dejedi)- nbd-vram es un pequeño daemon que permite usar la VRAM inactiva de una GPU NVIDIA en Linux como espacio de swap de alta prioridad
- En laptops con gráficos híbridos donde la memoria está soldada y es difícil de ampliar, y la GPU integrada AMD/ATI se encarga de la salida de video, aprovecha la VRAM NVIDIA ociosa para aliviar la presión de memoria
- El entorno de prueba es AMD/ATI + RTX 3070 Laptop, RAM 16GB, VRAM 8GB, NVIDIA driver 580.159.03, kernel 6.17 y Pop!_OS; se asignan 7GB de VRAM como swap y, junto con zram y swap en SSD, se construyen unos 46GB de memoria direccionable
- El orden de funcionamiento es que primero se llena la RAM, luego la VRAM absorbe las páginas desbordadas a través de PCIe, después zram las comprime en la CPU y, al final, se usa el SSD
- El daemon asigna VRAM con la API del driver de CUDA y ofrece un dispositivo de bloques mediante el protocolo NBD (Network Block Device) sobre un socket Unix; el driver integrado
nbddel kernel lo expone como/dev/nbdXpara usarlo como un dispositivo de swap normal - La ruta de datos sigue kernel swap subsystem →
/dev/nbdX→ nbd kernel driver → Unix socket → nbd-vram daemon →cuMemcpyHtoD/DtoH→ VRAM de la GPU - No requiere un módulo de kernel aparte ni símbolos del kernel de NVIDIA, por lo que puede mantenerse sin recompilar incluso después de actualizar el kernel o el driver
- El enfoque con la API NVIDIA P2P falla en GPUs GeForce de consumo porque
nvidia_p2p_get_pages_persistentdevuelveEINVAL, y el método de acceso directo BAR1 conioremap_wctambién falla porque las lecturas fuera de unos 16MiB del framebuffer de pantalla devuelven 0 - La ruta de copia de CUDA,
cuMemcpyHtoDycuMemcpyDtoH, funciona en GPUs CUDA sin privilegios especiales, por lo que el acceso vía NBD evita las restricciones de P2P y BAR1 - Los requisitos son una GPU NVIDIA compatible con CUDA, driver de NVIDIA con
libcuda.so.1, el módulo nbd de Linux kernel 3.0+,nbd-client,gccymake; no se necesita el toolkit de CUDA - Después de la instalación, el servicio systemd
vram-swap-nbdse ejecuta automáticamente al arrancar, y en/etc/systemd/system/vram-swap-nbd.servicese ajustan conVRAM_SETUP_SIZE_MByVRAM_SWAP_PRIORITYel límite superior de VRAM a usar y la prioridad del swap - El daemon primero intenta asignar el tamaño de VRAM solicitado y, si falta memoria en la GPU, lo reduce en bloques de 512MiB; por eso
VRAM_SETUP_SIZE_MBno funciona como tamaño obligatorio sino como límite superior - Si se activa la gestión con reconocimiento de energía, el servicio se detiene automáticamente al desconectar la corriente AC o al bajar de un umbral de batería, y se reinicia cuando vuelve la energía; un
systemctl stopmanual no se sobrescribe - En benchmarks con una RTX 3070 Laptop, el NVMe es más rápido en rendimiento secuencial y en I/O aleatorio sostenido, pero en latencia de lectura 4K a 1 request/sec la VRAM promedia 335us, 27 veces más rápida que los 9.05ms del NVMe
- Se ofrece bajo licencia MIT, y el repositorio incluye
test-nbd.shpara smoke tests,test-fill.shpara verificar particiones completas, y scripts de benchmark de throughput, IOPS y latencia
1 comentarios
Comentarios de Hacker News
Si se maneja a través de CUDA como si fuera almacenamiento de archivos o un montaje, la sobrecarga es alta; usando BAR probablemente se podría mejorar claramente el rendimiento y los IOPS
Si la explicación es que esto es para laptops con memoria soldada y sin ruta de actualización, entonces responde a la duda inmediata de por qué usar swap desde RAM cara hacia RAM todavía más cara
El caso de uso parece limitado, pero usar 8 GB de VRAM que están ociosos cuando el sistema está swapeando al SSD sí suena como una buena idea cuando hace falta
Por ejemplo, si compraste la GPU para jugar, cuando no estás jugando no necesitas 16 GB de VRAM para renderizar el escritorio, así que quizá podría usarse para otra cosa
Eso sí, habría que asumir que el sistema puede liberar la VRAM que estaba usando como swap al iniciar un juego, y me pregunto si eso realmente es posible
En los Amstrad PCW, que eran muy comunes en Reino Unido desde mediados de los 80 hasta mediados de los 90, podías usar hasta 512 kB de RAM, y una parte bastante grande podía convertirse en RAM disk
Incluso al compilar con Turbo Pascal se notaba muchísimo la velocidad :-)
La idea es buena, pero aquí parece que algo está muy mal
Dicen que en una RTX 3070 Laptop el rendimiento secuencial es de unos 1.3 GB/s, pero ese chip RTX 3070 es PCIe 4.0 x16, así que debería dar 64 GB/s, y los 8 GB de GDDR6 por sí solos son 448 GB/s
Hacer swap a un disco NVMe probablemente sería el doble de rápido, aunque con mayor latencia
Además, el benchmark se hizo usando ZRAM, y ZRAM comprime las páginas antes de escribirlas al swap. No sé exactamente cuánto cuesta ese overhead en rendimiento, pero seguramente es considerable
Para empezar, el programa en espacio de usuario va montado sobre el driver nbd, que ya es conocido por ser lento, y además usa un bounce buffer en espacio de usuario antes de transferir al GPU. Si el kernel necesita swappear una página, primero la copia a un buffer expuesto al espacio de usuario, luego el programa de espacio de usuario tiene que despertarse otra vez y emitir operaciones CUDA para copiar esa página a la memoria del dispositivo
nbd tampoco soporta bien profundidades de cola altas ni la fusión de accesos contiguos. Si el kernel emite muchas operaciones de swap de páginas de 4K sin fusionar, incluso para sostener solo 4 GB/s harían falta al menos un millón de cambios de contexto kernel/espacio de usuario por segundo. Ni hablar de 64 GB/s. Y eso viendo solo la parte de NBD, sin contar la complejidad del driver de NVIDIA
PCIe puede mover mucho volumen de datos, pero para acercarte al ancho de banda total necesitas un motor DMA con listas largas de páginas. Si configuras una transferencia por cada página de 4K en PCIe, no vas a saturar el bus por completo
La ruta de swap hacia NVMe está muy optimizada. El swapper puede enviar listas de páginas directamente al driver de NVMe, y el controlador las obtiene por DMA directamente desde la RAM, sin copias del lado de CPU ni cambios de contexto
Si se migrara al driver ublk, quizá se podría evitar el bounce buffer en espacio de usuario, y también podría mejorarse configurando copias CUDA en paralelo con varias colas de escritura
La RAM o la VRAM no se degradan por usarse
En mi máquina de desarrollo tengo 32 GB de RAM y 32 GB de VRAM que casi siempre están sin hacer nada cuando no estoy corriendo modelos de IA, así que la idea no me parece tan mala
Me pregunto cómo manejan la contrapresión. ¿Qué pasa si llega una solicitud de asignación de VRAM mientras la VRAM está usándose como espacio de swap?
En X11 los buffers se preasignan, así que no es tan grave, pero en Wayland las asignaciones son mucho más dinámicas, así que si te quedas sin VRAM se puede morir fácilmente todo el escritorio
Me pasó varias veces ese tipo de choque con Hyprland+llama-server+KVM al cambiar la computadora y no poder liberar la VRAM
Crear un dispositivo de swap a nivel de usuario ha sido desde hace mucho uno de esos problemas clásicos supuestamente imposibles de resolver
Si el daemon necesita hacer swap-in de una página, pero para traer esa página primero tendría que hacer swap-in de sus propias páginas, ¿entonces qué haces?
Al menos recuerdo discusiones de este tipo como una de las razones por las que supuestamente un microkernel nunca podría funcionar. Aquí no me queda claro cuál es la solución
El kernel de Linux también evita que sus propias páginas de texto se swapeen, así que la solución ya existe, y no veo por qué no se podría aplicar también a diseños de microkernel
Si fijas en memoria toda la del daemon, este problema se resuelve de forma trivial
Recuerdo haber hecho algo parecido hace tiempo con el driver MTD/phram de Linux: https://wiki.archlinux.org/title/Swap_on_video_RAM
Aunque no sé si siga siendo relevante hoy, porque no sé cómo interactúa con DRM ni cómo se maneja la reserva de una parte de la VRAM. La idea de sugerir límites con xorg.conf probablemente ya esté bastante anticuada
Esa página también tiene un sistema de archivos FUSE implementado sobre OpenCL: https://github.com/Overv/vramfs
Puede que esa opción sea más compatible
Qué recuerdos
También vi algo parecido en Windows hace algunos años
Era un driver experimental de prueba de concepto que permitía crear un RAM drive con la VRAM de una tarjeta NVIDIA, y el acceso secuencial era rápido como era de esperarse, aunque el acceso aleatorio todavía tenía bastante margen de mejora
GpuRamDrive crea una unidad virtual respaldada por RAM de GPU: https://github.com/prsyahmi/GpuRamDrive
Fork con soporte para AMD: https://github.com/brzz/GpuRamDrive/
Es parecido, pero usa la API de OpenCL, así que también funciona en AMD
Aunque los drivers de AMD tienen bastantes bugs, así que habría que definir qué significa exactamente “funciona”: https://libguestfs.org/nbdkit-vram-plugin.1.html
No entiendo por qué una Mac Apple Silicon con 32 GB de RAM sigue usando o incluso creando archivos de swap cuando todavía tiene 20 GB sin usar o marcados como “free”
¿Por qué no existe algo tan simple como
swapoff -aen Linux para desactivar por completo el archivo de swap?Si el objetivo no es reducir deliberadamente la vida útil del SSD, se ve bastante tonto
Estaría bien tener una configuración del sistema en la GUI para desactivar el archivo de swap, y también estaría bien que Apple por fin abandonara la “etapa” actual de configuración/diseño del sistema. Comparado con décadas del panel de preferencias, esto todavía parece una ensalada de palabras
#Apple #Feedback #swapfile
Incluso el concepto de “memoria disponible” idealmente se parece más a “memoria que puede recuperarse rápidamente para otro propósito”
A veces conviene más que el contenido de archivos cacheados ocupe ese espacio, en vez de mantener memoria anónima en la memoria principal todo el tiempo