Introduction à RCU
- Un système d’exploitation fait partie, au quotidien, des programmes les plus sensibles aux performances.
- Un système d’exploitation peut toujours être plus rapide, et les développeurs de noyaux et de pilotes s’emploient à optimiser le code.
- Un système d’exploitation exige une concurrence massive, planifie les processus et threads en espace utilisateur, et dispose de ses propres threads ainsi que de gestionnaires d’interruptions qui interagissent avec le matériel.
Principe de fonctionnement de RCU
- Lorsqu’il faut modifier de façon atomique des données souvent lues mais rarement écrites (par exemple les périphériques USB actuellement connectés), on utilise la stratégie RCU (Read, Copy, Update).
- On lit les données, on les copie pour les modifier, puis on met à jour de façon atomique le pointeur vers la nouvelle version.
- Cette méthode est facile à utiliser et sans attente, mais elle peut entraîner des fuites mémoire.
Résoudre le problème des fuites mémoire
- Pour éviter les fuites mémoire, au lieu de supprimer les anciennes données dans la fonction de mise à jour, on peut différer leur suppression jusqu’à ce qu’il n’y ait plus de lecteur en train de les lire.
- Pendant que les lecteurs lisent les données, l’auteur de l’écriture attend la suppression des données afin de gérer la mémoire en toute sécurité.
Utilisation concrète de RCU
- RCU est utilisé des dizaines de milliers de fois dans Linux, ainsi que dans la bibliothèque C++ Folly de Facebook et dans
crossbeam-epoch en Rust.
- RCU est motivé par des exigences de performance et de latence, et fournit une méthode de gestion mémoire semblable au ramasse-miettes.
Idées reçues sur le ramasse-miettes
- L’idée reçue selon laquelle le ramasse-miettes serait plus lent que la gestion manuelle de la mémoire s’effondre vite dès qu’on examine les détails.
- La fonction
free() n’est pas gratuite, et l’allocateur mémoire doit conserver en interne beaucoup d’état.
- Les ramasse-miettes modernes offrent des optimisations par déplacement et par générations, avec un débit élevé et de bonnes performances de cache.
L’illusion du contrôle
- Les développeurs veulent parfois construire des systèmes temps réel, mais en pratique ils n’ont pas un contrôle total sur la gestion de la mémoire.
- Le système d’exploitation ne fait que deviner les intentions du développeur en matière d’allocation mémoire, et il arrive qu’un simple accès à un pointeur se transforme en E/S disque.
Conclusion
- Tous les logiciels ne tirent pas profit du ramasse-miettes, mais c’est un outil utile qui ne devrait plus inspirer de crainte, même chez les programmeurs système.
L’avis de GN⁺
- RCU est une technique efficace pour accroître la concurrence tout en maintenant la cohérence des données dans un environnement multithread. C’est un élément très important dans le calcul haute performance et les systèmes temps réel.
- L’exemple de RCU, qui bouscule les idées reçues sur le ramasse-miettes, offre aux développeurs une nouvelle perspective sur la gestion de la mémoire. C’est d’autant plus vrai dans le domaine de la programmation système, où la gestion mémoire est essentielle.
- Parmi les autres projets offrant des fonctionnalités proches de RCU, on peut citer
ConcurrentLinkedQueue de Java ou ConcurrentBag de .NET, qui fournissent eux aussi des structures de données lock-free.
- Lorsqu’on adopte la technologie RCU, il faut prendre en compte les exigences du système et les objectifs de performance, et comprendre les bénéfices comme les coûts potentiels de son utilisation.
- Cet article peut aider les développeurs à mieux comprendre la gestion de la mémoire et la concurrence, à remettre en question leurs hypothèses existantes et à explorer de nouvelles solutions.
1 commentaires
Avis Hacker News
Suggestion de jeter un œil aux techniques innovantes de garbage collection (GC) parallèle de MPL et MaPLe
L’utilisation de RCU comme mécanisme de synchronisation pour la garbage collection est intéressante
Idées reçues générales sur la gestion mémoire
Le cas d’usage de RCU est convaincant, mais l’expérience de la garbage collection dans d’autres contextes est médiocre
free()rend la mémoire au système d’exploitationAvec la garbage collection, les nouvelles allocations se font en RAM plutôt que dans le cache
Une bonne garbage collection par traçage dépasse depuis longtemps la gestion mémoire manuelle en termes de débit
L’un des éléments qui se marient bien avec la garbage collection est async/await
Il est quelque peu surprenant de passer d’une motivation autour de RCU à une discussion sur la garbage collection générale
En développement logiciel, deux cas sont pris en compte
Le passage de RCU à une garbage collection par traçage générale ressemble à une stratégie habile
Il est difficile pour les programmeurs système d’identifier quand un objet peut être garbage collecté
Les outils de gestion du cycle de vie en Rust et en C++ aident à automatiser la libération mémoire, mais ne simplifient pas la complexité