nbd-vram - Un outil pour utiliser la VRAM d’un GPU NVIDIA comme espace de swap sous Linux
(github.com/c0dejedi)- nbd-vram est un petit démon qui permet d’utiliser la VRAM inutilisée d’un GPU NVIDIA sous Linux comme espace de swap à haute priorité
- Sur les ordinateurs portables à graphisme hybride, où la mémoire est soudée donc difficile à mettre à niveau et où le GPU intégré AMD/ATI assure l’affichage, il exploite la VRAM NVIDIA inutilisée pour atténuer la pression mémoire
- L’environnement de test est un AMD/ATI + RTX 3070 Laptop, avec 16 Go de RAM, 8 Go de VRAM, le pilote NVIDIA 580.159.03, le kernel 6.17 et Pop!_OS ; 7 Go de VRAM ont été alloués au swap, pour constituer environ 46 Go de mémoire adressable en combinant zram et le swap SSD
- L’ordre de fonctionnement est le suivant : la RAM se remplit d’abord, puis la VRAM absorbe via PCIe les pages qui débordent, ensuite zram compresse côté CPU, et enfin le SSD est utilisé en dernier recours
- Le démon alloue la VRAM via l’API du pilote CUDA, fournit un périphérique bloc via le protocole NBD (Network Block Device) sur un socket Unix, et le pilote
nbdintégré au kernel l’expose comme/dev/nbdXpour l’utiliser comme un périphérique de swap classique - Le chemin des données est : kernel swap subsystem →
/dev/nbdX→ nbd kernel driver → Unix socket → nbd-vram daemon →cuMemcpyHtoD/DtoH→ VRAM du GPU - Aucun module kernel séparé ni symbole kernel NVIDIA n’est nécessaire, ce qui permet de conserver le fonctionnement après une mise à jour du kernel ou du pilote sans recompilation
- Avec l’approche via l’API NVIDIA P2P,
nvidia_p2p_get_pages_persistentrenvoieEINVALsur les GPU GeForce grand public, et l’approche d’accès direct BAR1 viaioremap_wcéchoue aussi, car les lectures hors de la zone d’environ 16 MiB du framebuffer d’affichage renvoient 0 - Le chemin de copie CUDA via
cuMemcpyHtoDetcuMemcpyDtoHfonctionne sur les GPU CUDA sans privilèges particuliers, ce qui permet à l’accès NBD de contourner les limitations de P2P et de BAR1 - Les prérequis sont un GPU NVIDIA compatible CUDA, un pilote NVIDIA avec
libcuda.so.1, le module nbd du kernel Linux 3.0+,nbd-client,gccetmake; le toolkit CUDA n’est pas nécessaire - Après l’installation, le service systemd
vram-swap-nbdse lance automatiquement au démarrage, etVRAM_SETUP_SIZE_MBainsi queVRAM_SWAP_PRIORITYdans/etc/systemd/system/vram-swap-nbd.servicepermettent d’ajuster la limite de VRAM utilisée et la priorité du swap - Le démon essaie d’abord la taille de VRAM demandée puis, si la mémoire GPU est insuffisante, réduit l’allocation par paliers de 512 MiB ;
VRAM_SETUP_SIZE_MBagit donc comme une limite maximale et non comme une taille obligatoire - Si la gestion tenant compte de l’alimentation est activée, le service s’arrête automatiquement lors du débranchement du secteur ou sous un seuil critique de batterie, puis redémarre quand l’alimentation revient ; un
systemctl stopmanuel n’est pas écrasé - Dans les benchmarks sur RTX 3070 Laptop, le NVMe est plus rapide en débit séquentiel et en I/O aléatoires soutenues, mais en latence de lecture 4K à 1 request/sec, la VRAM atteint une moyenne de 335us, soit 27 fois plus rapide que les 9.05ms du NVMe
- Le projet est proposé sous licence MIT, et le dépôt fournit aussi
test-nbd.shpour les smoke tests,test-fill.shpour la vérification d’une partition complète, ainsi que des scripts de benchmark pour le débit, les IOPS et la latence
1 commentaires
Commentaires sur Hacker News
Si on le traite via CUDA comme un stockage de fichiers ou un montage, la surcharge est importante, donc avec le BAR, on pourrait sans doute nettement améliorer le débit et les IOPS
Si l’idée est que c’est destiné aux ordinateurs portables avec mémoire soudée et sans possibilité d’upgrade, ça répond à la question immédiate de savoir pourquoi on ferait du swap depuis de la RAM chère vers une RAM encore plus chère
L’usage semble limité, mais utiliser 8 Go de VRAM inutilisés lorsqu’on commence à swapper sur SSD est une bonne idée quand on en a besoin
Par exemple, si on a acheté un GPU pour jouer, quand on ne joue pas, on n’a pas besoin de 16 Go de VRAM pour le rendu du bureau, donc pourquoi ne pas les utiliser à autre chose ?
Cela dit, il faut supposer que le système puisse libérer la VRAM utilisée comme swap au moment de lancer un jeu, et je me demande si c’est réellement possible
Sur les Amstrad PCW, très répandus au Royaume-Uni du milieu des années 80 au milieu des années 90, on pouvait utiliser jusqu’à 512 ko de RAM, dont une part assez importante pouvait devenir un RAM disk
Même la compilation avec Turbo Pascal devenait très rapide :-)
L’idée est bonne, mais il semble y avoir quelque chose de très mal fichu ici
On parle d’environ 1,3 Go/s de débit séquentiel sur un RTX 3070 Laptop, alors que cette puce RTX 3070 est en PCIe 4.0 x16 et devrait atteindre 64 Go/s, et que ses 8 Go de GDDR6 montent eux-mêmes à 448 Go/s
Swapper sur un disque NVMe serait deux fois plus rapide, mais avec une latence plus élevée
En plus, le benchmark a été lancé avec ZRAM, qui compresse les pages avant de les écrire dans le swap. Je ne sais pas exactement quelle est la surcharge de performance, mais elle est probablement importante
Déjà, on passe par un programme en espace utilisateur accroché au pilote nbd, connu pour être lent, et on utilise aussi un buffer de rebond en espace utilisateur avant le transfert vers le GPU. Si le noyau doit swapper une page, il doit d’abord la copier vers un buffer exposé à l’espace utilisateur, puis le programme utilisateur doit se réveiller de nouveau, lancer des opérations CUDA et recopier cette page vers la mémoire du périphérique
nbd ne gère pas non plus très bien les profondeurs de file d’attente élevées ni la fusion des accès adjacents. Si le noyau émet beaucoup de swaps de pages de 4K sans fusion, même atteindre 4 Go/s demande au moins un million de changements de contexte noyau/espace utilisateur par seconde. Alors 64 Go/s, n’en parlons même pas. Et ça, c’est seulement la partie NBD, sans même compter la complexité du pilote NVIDIA
Le PCIe peut déplacer beaucoup de données, mais pour approcher la bande passante totale, il faut utiliser un moteur DMA avec de longues listes de pages. Si on configure un transfert sur PCIe pour chaque page de 4K, on ne saturera jamais complètement le bus
Le chemin de swap vers NVMe, lui, est extrêmement optimisé. Le swapper peut soumettre directement des listes de pages au pilote NVMe, et le contrôleur vient les récupérer par DMA directement depuis la RAM, sans aucune copie côté CPU ni changement de contexte
En passant au pilote ublk, on pourrait peut-être éviter le buffer de rebond en espace utilisateur, et il serait aussi possible de configurer en parallèle des copies CUDA sur plusieurs files d’écriture, donc il y a sans doute de la marge d’amélioration
La RAM ou la VRAM, elles, ne se dégradent pas à l’usage
J’ai une machine de développement avec 32 Go de RAM et 32 Go de VRAM qui restent la plupart du temps inutilisés quand je ne fais pas tourner de modèles d’IA, donc l’idée n’est pas si mauvaise
Je me demande comment est gérée la contre-pression. Que se passe-t-il si une demande d’allocation de VRAM arrive pendant que la VRAM sert d’espace de swap ?
Sous X11, les buffers sont préalloués, donc ce n’est pas trop grave, mais sous Wayland les allocations sont bien plus dynamiques, donc si la VRAM vient à manquer, tout le bureau peut facilement mourir
Ça m’est arrivé plusieurs fois en basculant la machine avec Hyprland+llama-server+KVM, faute d’avoir pu libérer la VRAM
Créer un périphérique de swap au niveau utilisateur fait partie depuis longtemps des problèmes classiques réputés insolubles
Si le démon doit swap-in une page, mais qu’il doit d’abord swap-in ses propres pages pour pouvoir le faire, qu’est-ce qu’on fait ?
Il y avait au moins ce genre de discussions comme raison pour laquelle les microkernels ne pourraient jamais fonctionner. Je ne vois pas bien quelle est la solution ici
Le noyau Linux empêche déjà que ses propres pages de texte soient swap-out, donc la solution existe déjà, et je ne vois pas pourquoi elle ne s’appliquerait pas aussi à la conception des microkernels
Si on verrouille en mémoire toute la mémoire de ce démon, le problème devient trivial à résoudre
Je me souviens avoir fait quelque chose de similaire autrefois avec le pilote MTD/phram de Linux : https://wiki.archlinux.org/title/Swap_on_video_RAM
Je ne sais pas si c’est encore pertinent aujourd’hui, parce que je ne sais pas comment cela interagit avec DRM ni comment on gère la réservation d’une partie de la VRAM. La méthode qui consiste à proposer une limitation via xorg.conf est probablement assez dépassée maintenant
Cette page mentionne aussi un système de fichiers FUSE implémenté au-dessus d’OpenCL : https://github.com/Overv/vramfs
Ça pourrait être plus compatible
Ça rappelle des souvenirs
J’ai déjà vu quelque chose de similaire sous Windows il y a quelques années
C’était un pilote expérimental de preuve de concept permettant de créer un RAM drive à partir de la VRAM d’une carte NVIDIA, et les accès séquentiels étaient rapides comme prévu, mais les accès aléatoires laissaient encore beaucoup de marge d’amélioration
GpuRamDrive crée un lecteur virtuel soutenu par la RAM du GPU : https://github.com/prsyahmi/GpuRamDrive
Fork avec support AMD : https://github.com/brzz/GpuRamDrive/
C’est similaire, mais en utilisant l’API OpenCL, donc ça fonctionne aussi sur AMD
Cela dit, les pilotes AMD sont assez bogués, donc il faut définir ce qu’on entend par « fonctionne » : https://libguestfs.org/nbdkit-vram-plugin.1.html
Je ne comprends pas pourquoi, sur un Mac Apple Silicon avec 32 Go de RAM, il utilise ou crée même un fichier de swap alors qu’il reste encore 20 Go inutilisés / « free »
Pourquoi n’existe-t-il pas une commande simple comme
swapoff -asous Linux pour désactiver complètement le fichier de swap ?Si le but n’est pas de réduire volontairement la durée de vie du SSD, ça paraît assez absurde
Ce serait bien d’avoir un réglage système dans l’interface graphique pour désactiver le fichier de swap, et Apple pourrait aussi enfin abandonner les « étapes » actuelles de son agencement des réglages système. Comparé aux panneaux de préférences de plusieurs décennies, ça ressemble encore à une salade de mots
#Apple #Feedback #swapfile
Même la notion de « mémoire disponible » est idéalement plus proche de « mémoire qu’on peut récupérer rapidement pour un autre usage »
À certains moments, il vaut mieux laisser des contenus de fichiers en cache occuper cette place plutôt que de conserver de la mémoire anonyme en mémoire principale