- Exploration de l’implémentation des pipes Unix sous Linux et des méthodes d’optimisation de programmes de test qui écrivent et lisent des données via des pipes
- Le programme initial avait un débit d’environ 3,5 Gio/s, amélioré d’un facteur 20 grâce à diverses optimisations
- Ces optimisations ont été réalisées en profilant le programme avec l’outil
perf de Linux
- L’article s’inspire d’un programme FizzBuzz optimisé qui pousse des sorties dans un pipe à une vitesse d’environ 35 Gio/s
- Analyse approfondie du fonctionnement interne des pipes, des raisons pour lesquelles écrire et lire depuis ceux-ci est lent, et de la manière dont les appels système
vmsplice et splice améliorent les performances
- Discussion sur la manière dont la pagination Linux et l’utilisation de huge pages peuvent conduire à des versions plus rapides du programme
- L’optimisation finale consiste à remplacer le polling par une boucle active
- Les tests ont été effectués sur un CPU Intel Skylake i7-8550U et Linux 5.17
- L’article explique en détail comment la mémoire est composée de pages de taille fixe et comment le CPU utilise les tables de pages pour traduire les adresses virtuelles en adresses physiques
- L’article conclut en observant qu’un passage aux huge pages dans le programme améliore les performances d’environ 50 %
- L’article aborde l’utilisation des huge pages dans le CPU et la manière de réduire les défauts de Translation Lookaside Buffer (TLB), ce qui peut améliorer les performances
- Le code du noyau suppose que
struct page pointe vers une page de taille standard pour l’architecture actuelle. Dans le cas des huge pages, la struct page « head » contient les informations sur la page physique réelle, tandis que les pages « tail » consécutives ne contiennent qu’un pointeur vers la page head
- Les noyaux récents (après 5.17) incluent
struct folio, un nouveau type qui identifie explicitement la page head. Cela améliore les performances en réduisant le besoin de vérifier à l’exécution si une struct page est une page head ou tail
- L’article discute du concept de boucle active pour éviter le coût de la synchronisation. Cela consiste à demander à
vmsplice de retourner lorsqu’il est impossible d’écrire dans le pipe, puis à tourner en boucle active jusqu’à ce qu’il soit prêt. Cela peut apporter un gain de performance de 25 %, mais au prix d’une occupation complète d’un cœur CPU jusqu’à ce que vmsplice soit prêt
- L’auteur résume les principaux thèmes abordés dans l’article : opérations zero-copy, buffer circulaire, pagination et mémoire virtuelle, surcharge de synchronisation
- L’auteur reconnaît également qu’il existe de nombreuses autres options et détails non abordés dans l’article, soit parce qu’ils ne sont pas pertinents, soit par manque d’intérêt
- L’article a été bien accueilli par les lecteurs, qui l’ont trouvé utile et intéressant
1 commentaires
Commentaires Hacker News
vmsplice, qui fonctionne comme un mini-mécanisme de mémoire partagée entre deux processusvmspliceexige une gestion soigneuse des buffers à la lecture et à l’écriture ; c’est complexe, mais cela peut être efficacesplice()etvmsplice(), jugées difficiles à utiliser dans la plupart des programmes et donc peu exploitéesstdoutd’un programme vers lestdind’un autre, ce qui transforme l’opération enzerocopyou, dans des cas moins optimisés, enonecopyrapideperfet souligne leur importance pour le débitcat,sed,awk,cut,grep,uniqetjq