
Qu’est-ce que Firedancer ? Plongée au cœur de Solana 2.0
Sommaire
- De quoi parle cet article ?
- Que sont les validateurs et la diversité des clients de validation ?
- Pourquoi Jump développe-t-elle un nouveau client de validation ?
- Pourquoi la vitesse de la lumière est-elle trop lente ?
- Qu’est-ce que Firedancer ?
- Comment fonctionne Firedancer ?
- Architecture modulaire
- Traitement réseau
- Système de build
- Pourquoi Firedancer est-il si rapide ?
- Parallélisme avancé des données
- Exploiter les FPGA pour des communications réseau à haut débit
- Optimiser le codage Reed-Solomon pour les communications réseau
- Comment Firedancer est-il sécurisé ?
- Opportunités
- Défis
- Mettre en œuvre une défense en profondeur dès la conception
- Mettre en œuvre un programme de sécurité intégré
- Où en est Firedancer et qu’est-ce que Frankendancer ?
- Qu’est-ce qui fonctionne réellement ?
- Quelles sont ses performances ?
- Frankendancer est opérationnel sur le testnet
- Conclusion
- Ressources supplémentaires / Pour aller plus loin
- Annexe
- Introduction au matériel informatique et aux réseaux
- Unité centrale de traitement (CPU)
- Processeur graphique (GPU)
- Mémoire vive (RAM)
- Stockage sur disque
- Carte mère
- Trafic entrant et sortant
- Pipelines et parallélisme des données
- Réseau de portes programmables (FPGA)
Un immense merci à l’équipe de Firedancer pour sa relecture de cet article.
De quoi parle cet article ?
Solana est la blockchain la plus rapide. Mais elle peut l’être encore davantage. Le client de validation actuel de Solana Labs est performant, mais optimisé pour une mise sur le marché rapide. Avec le recul, en repartant de zéro et forte de plusieurs décennies d’expérience dans le calcul haute performance, Jump s’attache à rendre Solana encore plus rapide et plus fiable. En s’appuyant sur son expérience du trading haute fréquence, Jump développe Firedancer. Il s’agit du client de validation le plus performant de toutes les blockchains. Il propose une réécriture complète du client de validation actuel de Solana dans le langage de programmation C.
Cet article présente les validateurs et l’importance de la diversité des clients de validation. Nous verrons ensuite pourquoi Jump développe un nouveau client de validation et en quoi son expérience du trading haute fréquence en fait l’équipe idéale pour développer Firedancer. Puis, nous expliquerons ce qu’est Firedancer, comment il fonctionne, pourquoi il est rapide, comment il est sécurisé et où en est son développement.
À la fin de cet article, vous comprendrez en détail le nouveau client de validation de Jump. Vous connaîtrez ses optimisations révolutionnaires, qui en font le client de validation le plus performant de toutes les blockchains. Vous comprendrez également pourquoi Firedancer est essentiel aux performances et à la fiabilité du réseau Solana. Cet article est le seul dont vous avez besoin pour tout savoir sur Firedancer.
L’annexe contient une introduction entièrement facultative au matériel informatique et aux réseaux. Elle a été ajoutée pour fournir au lecteur moyen le contexte nécessaire afin de comprendre les concepts plus avancés de matériel et de réseau abordés dans cet article. Du contexte est néanmoins fourni lorsque cela s’avère nécessaire. Cet article se veut accessible afin que toute personne utilisant Solana puisse comprendre Firedancer et son importance.
Que sont les validateurs et la diversité des clients de validation ?
Un validateur est un ordinateur qui participe à une blockchain fondée sur la preuve d’enjeu. Les validateurs constituent l’épine dorsale du réseau Solana. Ils sont chargés de traiter les transactions et de participer au consensus. Un validateur contribue à sécuriser le réseau en immobilisant comme enjeu une certaine quantité du jeton natif de Solana. Considérez cela comme un dépôt de garantie qui expose financièrement le validateur au réseau. Cette exposition incite les validateurs à accomplir leurs tâches avec précision et efficacité, puisqu’ils reçoivent des récompenses pour leurs contributions. Les validateurs sont également sanctionnés en cas d’activité malveillante ou défaillante. L’enjeu d’un validateur est réduit en cas de comportement inapproprié, selon un processus appelé slashing. Un validateur a donc tout intérêt à remplir correctement ses fonctions pour accroître son enjeu.
Les clients de validation sont les applications que les validateurs utilisent pour remplir leurs fonctions. Le client sert de base aux validateurs, qui utilisent leur identité cryptographique unique pour participer au consensus.
Disposer de plusieurs clients distincts améliore la tolérance aux pannes lorsqu’une implémentation échoue. Par exemple, si aucun client ne contrôle plus de 33 % de l’enjeu, une panne ou un bug affectant la disponibilité ne mettra pas le réseau hors service. De même, si un bug dans un client entraîne une transition d’état non valide, le réseau peut éviter une défaillance de sécurité si moins de 33 % de l’enjeu utilise ce client. En effet, la majeure partie du réseau restera dans un état valide, ce qui empêchera une scission ou un fork de la blockchain. La diversité des clients de validation renforce donc la résilience du réseau, car un bug ou une vulnérabilité dans un client ne paralysera pas l’ensemble du réseau.
La diversité des clients se mesure au pourcentage d’enjeu traité par chacun d’eux et au nombre total de clients disponibles. Au moment de la rédaction de cet article, le réseau Solana compte 1 979 validateurs. Les deux clients que ces validateurs utilisent sur le mainnet sont fournis par Solana Labs et Jito Labs. Solana a été lancé avec un seul client de validation en mars 2020, développé par Solana Labs. En août 2022, Jito Labs a publié un deuxième client de validation. Ce client est un fork du code de Solana Labs maintenu et déployé par Jito. Le client optimise l’extraction de MEV (valeur maximale extractible) au sein des blocs. Le client de Jito crée un pseudo-mempool, puisque Solana diffuse les blocs sans en utiliser. Pour rappel, un mempool, ou pool de mémoire, est une file d’attente de transactions en attente et non confirmées. Un pseudo-mempool permet aux validateurs de parcourir ces transactions, de les regrouper de manière optimale et de les soumettre au Block Engine de Jito.
En octobre 2023, le client de Solana Labs détient 68,55 % de l’enjeu actif, contre 31,45 % pour Jito. Le nombre de validateurs utilisant le client de Jito a progressé de 16 % depuis le précédent rapport sur la santé de Solana Foundation. L’adoption croissante du client de Jito témoigne d’une évolution positive vers une plus grande diversité des clients.
Cette croissance est encourageante, mais la situation n’est pas parfaite. Il est essentiel de souligner que le client de Jito est un fork du client de Solana Labs. Cela signifie que Jito partage de nombreux composants avec le code source du validateur d’origine et peut donc être vulnérable aux bugs ou aux failles qui affecteraient le client de Labs. Dans l’idéal, Solana disposerait à terme d’au moins quatre clients de validation indépendants. Différentes équipes développeraient ces clients dans différents langages de programmation. Aucune implémentation ne détiendrait plus de 33 % de l’enjeu, chaque client en représentant environ ~25 %. Cette configuration idéale éliminerait tout point de défaillance unique dans l’ensemble de la pile du validateur.
Le développement d’un deuxième client de validation indépendant est indispensable pour concrétiser cet avenir, et Jump s’engage à y parvenir.
Pourquoi Jump développe-t-elle un nouveau client de validation ?
Le mainnet de Solana a déjà connu quatre interruptions de production de blocs. Chacune a nécessité des corrections manuelles par des centaines de validateurs. Ces interruptions ont mis en lumière les préoccupations relatives à la fiabilité du réseau Solana. Jump affirme que le protocole est solide. Elle attribue plutôt ces interruptions à des problèmes dans les modules logiciels affectant le consensus. Jump développe donc un nouveau client de validation pour résoudre ces problèmes. L’objectif global de ce client est d’améliorer la stabilité et l’efficacité du réseau Solana.
Développer un client de validation indépendant est une tâche difficile. Ce n’est toutefois pas la première fois que Jump construit un réseau mondial fiable. Par le passé, les transactions sur titres (c’est-à-dire l’achat et la vente d’actions) étaient exécutées manuellement par des spécialistes de marché. Avec l’émergence des plateformes de négociation électronique, les marchés de titres sont devenus plus ouverts. Cette ouverture a accru la concurrence et l’automatisation, tout en réduisant le temps et le coût des opérations pour les investisseurs. Une course technologique s’est alors engagée entre les spécialistes de marché.
Les traders vivent pour négocier. Une expérience de trading optimale n’admet aucun compromis en matière de logiciels, de matériel et de solutions réseau. Ces systèmes doivent offrir une intelligence machine élevée, une faible latence en temps réel, un débit élevé, une grande adaptabilité, une forte évolutivité, une fiabilité élevée et une responsabilité accrue.
Les solutions standardisées (c’est-à-dire les logiciels qu’une entreprise peut acheter directement) ne constituent pas un avantage concurrentiel. Envoyer dix fois le bon ordre à une place boursière en arrivant en deuxième position est une manière coûteuse de perdre de l’argent. La concurrence acharnée du trading haute fréquence impose un cycle de développement perpétuel afin de construire une infrastructure de trading mondiale de premier ordre.
Ce scénario vous semble peut-être familier. Les exigences d’un système de trading performant ressemblent à celles d’une blockchain performante. Les blockchains doivent être des réseaux performants, tolérants aux pannes et à faible latence. Une blockchain lente est une technologie défaillante qui ne peut pas répondre aux exigences des applications d’entreprise modernes : elle ne fait qu’entraver l’innovation, l’évolutivité et l’utilité dans le monde réel. Avec plus de vingt ans d’expérience dans la mise à l’échelle de réseaux mondiaux et le développement de systèmes haute performance, Jump est l’équipe idéale pour créer un client de validation indépendant. Kevin Bowers, directeur scientifique de Jump Trading, supervise ce processus.
Pourquoi la vitesse de la lumière est-elle trop lente ?
Kevin Bowers a longuement expliqué pourquoi la vitesse de la lumière est trop lente. La vitesse de la lumière est une constante finie qui limite naturellement le nombre de calculs qu’un seul transistor peut traiter. Les bits sont actuellement modélisés par des électrons se déplaçant à travers des transistors. Le théorème de capacité de Shannon (c’est-à-dire la quantité maximale de données pouvant être transmises sans erreur sur un canal) limite le nombre de bits transmis à travers un transistor. En raison des lois fondamentales de la physique et de la théorie de l’information, la vitesse de calcul est limitée par la vitesse à laquelle un électron peut se déplacer dans la matière et par la quantité de données pouvant être transmise. Ces contraintes deviennent évidentes lorsque les superordinateurs sont poussés à leurs limites. Il en résulte un « décalage considérable entre la capacité des ordinateurs à effectuer des calculs et leur capacité à déplacer les nombres ».
Prenons comme exemple un CPU Intel Core i9 13900K. Il possède 24 cœurs x86, avec une fréquence de base de 2,2 GHz et une fréquence turbo maximale de 5,8 GHz. Dans le pire des cas, la lumière devrait parcourir une distance totale de ~52,0 mm à travers ce CPU. La distance de Manhattan du CPU (c’est-à-dire la distance entre deux points mesurée le long d’axes perpendiculaires) est de ~73,6 mm. À la fréquence turbo maximale du CPU de 5,8 GHz, la lumière peut parcourir ~51,7 mm dans l’air. Cela signifie qu’un signal peut presque effectuer un aller-retour complet entre deux points quelconques du CPU au cours d’un seul cycle d’horloge.
La réalité est bien pire. Ces mesures utilisent la vitesse de la lumière dans l’air, alors que ces signaux traversent du dioxyde de silicium (SiO2). La lumière peut parcourir ~26,2 mm dans le dioxyde de silicium pendant un cycle d’horloge à 5,8 GHz. Dans le silicium (Si), elle ne peut parcourir que ~15,0 mm pendant un cycle d’horloge à 5,8 GHz, soit un peu plus de la moitié du grand côté du CPU.
L’équipe de Firedancer estime que les progrès technologiques récents en informatique ont davantage consisté à intégrer plus de cœurs dans un CPU qu’à les rendre plus rapides. Lorsque davantage de performances étaient nécessaires, la solution recommandée consistait à acheter plus de matériel. Cela fonctionne pour l’instant lorsque le débit constitue le goulot d’étranglement. Mais le véritable goulot d’étranglement est la vitesse de la lumière. Cette limite naturelle paralyse la prise de décision. Aucune optimisation isolée n’offre de bénéfice immédiat, car un système comporte de nombreux composants et aucun n’est correctement optimisé. Les composants qui ne sont pas optimisés se dégraderont au fil du temps, car ils disposeront de moins de ressources de calcul. Que faire, alors ?
Dans le monde du calcul haute performance, tout doit finir par être optimisé. L’objectif est de construire des systèmes de trading en production et de recherche quantitative qui fonctionnent aux limites de la physique et de la théorie de l’information à l’échelle planétaire. Cela va de la création de technologies personnalisées de commutation réseau à des algorithmes sans verrou conçus en tenant compte de ces limites physiques. Jump est autant une entreprise technologique qu’une société de trading. À la frontière entre science-fiction et réalité, et face aux similitudes frappantes entre les problèmes rencontrés aujourd’hui par Jump et Solana, Jump développe Firedancer.
Qu’est-ce que Firedancer ?
Firedancer est un nouveau client de validation entièrement indépendant, développé par l’équipe de Firedancer dans le langage de programmation C. Firedancer a été conçu dans un souci de fiabilité grâce à son architecture modulaire, ses dépendances minimales et son processus de test approfondi. Il propose une réécriture majeure des trois composants fonctionnels du client de Solana Labs : réseau, environnement d’exécution et consensus. Chaque niveau est optimisé pour offrir des performances maximales, afin que le client fonctionne à une capacité limitée uniquement par le matériel du validateur. Cela diffère des limites de performances auxquelles les validateurs sont actuellement confrontés en raison d’inefficacités logicielles. Avec Firedancer, Solana évoluera au rythme de la bande passante et du matériel.
Les objectifs de Firedancer sont les suivants :
- Documenter et standardiser le protocole Solana (à terme, il devrait être possible de créer un validateur Solana uniquement à partir de la documentation, sans consulter le code Rust du validateur)
- Accroître la diversité des clients de validation
- Améliorer les performances de l’écosystème
Comment fonctionne Firedancer ?
Architecture modulaire
Firedancer se distingue des clients de validation Solana actuels par son architecture modulaire unique. Contrairement au client de validation Rust de Solana Labs, qui fonctionne comme un processus unique, Firedancer se compose de nombreux processus Linux C individuels appelés tiles. Une tile correspond à un processus et à une certaine quantité de mémoire. Cette architecture fondée sur les tiles est au cœur de la philosophie de fonctionnement de Firedancer et de son approche en matière de robustesse et d’efficacité.
Un processus est une instance d’un programme en cours d’exécution. Il s’agit d’un composant fondamental des systèmes d’exploitation modernes qui représente l’exécution d’un ensemble d’instructions. Chaque processus dispose de son propre espace mémoire et de ressources allouées par le système d’exploitation, et fonctionne indépendamment des autres processus. Un processus ressemble à un employé autonome dans une grande usine, chargé d’une tâche précise avec ses propres outils et son propre espace de travail.
Dans Firedancer, chaque tile est un processus individuel doté d’un rôle défini. Par exemple, la tile QUIC est chargée de traiter le trafic QUIC entrant et de transmettre les transactions encapsulées à la tile de vérification. Celle-ci se charge de vérifier les signatures, et ainsi de suite pour chaque tile. Ces tiles fonctionnent de manière indépendante et simultanée, contribuant au fonctionnement global du système. Les processus Linux individuels créent de petits domaines de défaillance indépendants. Cela signifie que les problèmes affectant une tile ont un impact minimal, ou un faible « rayon d’impact », sur l’ensemble du système. Cette approche diffère de celle du client Rust de Solana Labs, car un point de défaillance unique ne risque pas de compromettre instantanément l’ensemble du validateur.
L’un des principaux avantages de l’architecture de Firedancer est sa capacité à remplacer et à mettre à niveau chaque tile en quelques secondes, sans aucune interruption. Cette capacité contraste fortement avec le client Rust de Solana Labs, qui doit être entièrement arrêté avant toute mise à niveau. Cette différence tient à l’absence de stabilité de l’ABI (Application Binary Interface) dans Rust. Cela empêche les mises à niveau à la volée dans un environnement entièrement basé sur Rust. L’utilisation de processus C, qui bénéficient de la stabilité binaire du modèle d’exécution C, réduit considérablement les interruptions liées aux mises à niveau. Cela est possible parce que les tiles gèrent l’état du validateur dans différents espaces de travail. Ces objets de mémoire partagée persistent tant que le validateur reste sous tension. Chaque tile peut reprendre le traitement exactement là où elle l’avait interrompu lors d’un redémarrage ou d’une mise à niveau.
Dans l’ensemble, Firedancer repose sur une architecture par tiles adaptée à NUMA. Nous expliquerons ce que cela signifie dans la section suivante. Pour l’instant, retenez qu’elle fournit des ressources matérielles dédiées à chaque thread. Dans cette architecture, un cœur de CPU est utilisé par tile. Elle offre une transmission de messages haute performance entre les tiles, optimisée pour la localité de la mémoire, l’agencement des ressources et la latence des composants.
Traitement réseau
Le traitement réseau de Firedancer est conçu pour répondre aux exigences intensives du réseau Solana à mesure qu’il évolue vers des débits de plusieurs gigabits par seconde. Ce traitement se divise en activités entrantes et sortantes.
Les activités entrantes concernent principalement la réception des transactions envoyées par les utilisateurs. Les performances de Firedancer sont essentielles, car les messages de consensus peuvent être perdus si un validateur prend du retard dans le traitement des paquets. La bande passante opérationnelle actuelle d’un nœud Solana est de ~0,2 Gbps, tandis que le plus grand pic enregistré sur un nœud Jump a atteint ~40 GBps. Ce pic de bande passante illustre la nécessité d’une solution robuste et évolutive pour le traitement des données entrantes.
Les activités sortantes comprennent l’empaquetage des blocs, leur création et l’envoi des shreds. Chacune de ces étapes est essentielle au fonctionnement sécurisé et efficace du réseau Solana. Les performances de ces tâches influent non seulement sur le débit, mais aussi sur la fiabilité globale du réseau.
Firedancer vise à remédier aux faiblesses historiques de l’interface pair-à-pair de Solana pour le traitement des transactions. L’une de ses principales lacunes était l’absence de contrôle de congestion pour les transactions entrantes. Cette lacune a entraîné d’importantes interruptions du réseau le 14 septembre 2021 (17 heures) et le 30 avril 2022 (7 heures).
En réponse, Solana a apporté plusieurs améliorations à son réseau afin de gérer correctement de gros volumes de transactions. Firedancer suit cette voie en adoptant QUIC pour le contrôle des flux. QUIC est un protocole de transport réseau multiplexé qui constitue la base de HTTP/3. Il joue un rôle essentiel dans la protection contre les attaques DDoS et la gestion du trafic réseau. Il est toutefois important de noter que, dans certains cas, les coûts l’emportent sur les avantages. QUIC, associé au matériel spécialisé des centres de données pour atténuer les attaques DDoS, élimine l’intérêt de saturer le réseau de transactions.
La spécification de QUIC en 151 pages a considérablement complexifié le développement. Ne trouvant aucune bibliothèque C existante répondant à ses besoins en matière de licence, de performances et de fiabilité, l’équipe de Firedancer a développé sa propre implémentation. L’implémentation QUIC de Firedancer, surnommée fd_quic, introduit des structures de données et des algorithmes optimisés afin de réduire au minimum l’allocation de mémoire et d’éviter son épuisement.
La pile réseau personnalisée de Firedancer est au cœur de ses capacités de traitement. Elle a été conçue de zéro pour exploiter le receive-side scaling (RSS). RSS est une forme d’équilibrage de charge réseau accéléré par le matériel qui répartit le trafic réseau entre plusieurs cœurs de CPU afin d’accroître le parallélisme du traitement réseau. Chaque cœur de CPU gère une partie du trafic entrant avec une surcharge minimale. Cette approche surpasse l’équilibrage de charge logiciel traditionnel en éliminant le besoin de planificateurs complexes, de verrous et d’opérations atomiques.
Firedancer introduit un nouveau framework de transmission de messages pour composer une application à partir de tiles hautement performantes. Ces tiles peuvent contourner la pile réseau du noyau, limitée par son fonctionnement fondé sur les sockets, en utilisant AF_XDP. AF_XDP est une famille d’adresses optimisée pour le traitement haute performance des paquets. L’utilisation d’AF_XDP permet à Firedancer de lire directement les tampons des interfaces réseau.
Ce système de tiles permet d’intégrer différents concepts de calcul haute performance à la pile Firedancer. Cela comprend :
- Prise en compte de NUMA - NUMA (Non-Uniform Memory Access) est une architecture de mémoire informatique dans laquelle un processeur peut accéder à sa propre mémoire plus rapidement qu’à celle associée à un autre processeur. Pour Firedancer, la prise en compte de NUMA signifie que le client peut gérer efficacement la mémoire dans des configurations multiprocesseurs. C’est important pour le traitement de gros volumes de transactions, car cela optimise l’utilisation des ressources matérielles disponibles.
- Localité du cache - La localité du cache désigne l’utilisation de données déjà présentes dans un cache proche du processeur. Il s’agit généralement d’une forme complexe de localité temporelle (c’est-à-dire des données consultées récemment). Dans Firedancer, l’accent mis sur la localité du cache signifie que le système est conçu pour traiter les données réseau tout en réduisant la latence et en maximisant la vitesse.
- Concurrence sans verrou - La concurrence sans verrou désigne la conception d’algorithmes qui ne nécessitent aucun mécanisme de verrouillage, comme des mutex, pour gérer des opérations simultanées. Pour Firedancer, la concurrence sans verrou permet d’exécuter plusieurs opérations réseau en parallèle sans subir les retards dus aux verrous. Elle améliore la capacité de Firedancer à traiter simultanément un grand nombre de transactions.
- Pages mémoire de grande taille - L’utilisation de pages de grande taille dans la gestion de la mémoire facilite le traitement des jeux de données en réduisant les consultations de tables de pages et la fragmentation potentielle de la mémoire. Pour Firedancer, cela améliore l’efficacité de la gestion de la mémoire, ce qui est utile pour traiter de grands volumes de données réseau.
Système de build
Le système de build de Firedancer est conçu selon un ensemble de principes directeurs visant à garantir fiabilité et cohérence. Il cherche à réduire au minimum les dépendances externes et considère tous les outils participant au processus de build comme des dépendances à part entière. Cela implique de verrouiller chaque dépendance, y compris les compilateurs, sur une version précise. L’isolation de l’environnement pendant les étapes de build constitue un aspect essentiel de ce système. Elle améliore la portabilité, car le processus de build n’est pas affecté par l’environnement système.
Pourquoi Firedancer est-il si rapide ?
Parallélisme avancé des données
Pour les tâches cryptographiques telles que la vérification des signatures ED25519, Firedancer exploite le parallélisme avancé des données disponible dans les processeurs modernes. Les CPU modernes disposent d’instructions Single Instruction, Multiple Data (SIMD) permettant de traiter plusieurs éléments de données simultanément, ainsi que d’optimisations pour exécuter plusieurs instructions par cycle CPU. Il est généralement plus efficace en termes d’espace, de temps et d’énergie qu’une seule instruction traite en parallèle un tableau ou un vecteur d’éléments de données. À cet égard, les améliorations apportées au traitement parallèle des données peuvent avoir un effet plus important sur le débit que la seule augmentation de la vitesse de traitement.
Firedancer utilise notamment le parallélisme des données pour optimiser le calcul des vérifications de signatures. Cette approche permet de traiter simultanément des tableaux ou des vecteurs d’éléments de données afin de maximiser le débit et de réduire la latence. Cette implémentation d’ED25519 repose sur l’arithmétique des corps de Galois. Cette forme d’arithmétique est particulièrement adaptée aux algorithmes cryptographiques et aux calculs binaires. Dans les corps de Galois, les opérations telles que l’addition, la soustraction, la multiplication et la division sont définies de manière à correspondre à la nature binaire des systèmes informatiques. Voici un exemple de corps de Galois défini par 23 :
Le seul problème est qu’ED25519 utilise un corps de Galois défini par 2255-19. Considérez les éléments du corps comme des nombres compris entre 0 et 2255-19. Voici à quoi ressemblent les opérations de base :
- x + y → addition élémentaire modulo 2255-19
- x - y → soustraction élémentaire modulo 2255-19
- x * y → multiplication élémentaire modulo 2255-19
- 1/x → x à la puissance 2255-21 modulo 2255-19
L’addition, la soustraction et la multiplication correspondent presque à des calculs uint256_t (c’est-à-dire des calculs avec des entiers non signés, dont la valeur maximale est 2256-1). La division est difficile à calculer. Les CPU et GPU grand public n’effectuent pas de calculs uint256_t, encore moins de « quasi-calculs uint256_t », et moins encore ce type de division atypique et extrêmement complexe. Implémenter ce type de calcul avec des performances élevées dépend de notre capacité à l’émuler efficacement.
L’implémentation de Firedancer décompose les opérations arithmétiques en abordant les nombres de manière plus flexible. En appliquant les principes de la division et de la multiplication longues enseignées à l’école, où les retenues passent d’une colonne à l’autre, nous pouvons traiter ces colonnes en parallèle. Le moyen le plus rapide d’émuler ce type de calcul consiste à représenter un uint256_t sous la forme de six chiffres de 43 bits, avec une « retenue » de 9 bits. Cela permet d’utiliser les opérations 64 bits existantes des CPU tout en conservant suffisamment d’espace pour les bits de retenue. Cette organisation des nombres réduit le besoin de propager fréquemment les retenues et permet à Firedancer de traiter plus efficacement les grands nombres.
Cette implémentation exploite le parallélisme des données en réorganisant les calculs arithmétiques sous forme de sommes de colonnes parallélisées. Le traitement parallèle des colonnes accélère le calcul global en transformant ce qui aurait été un goulot d’étranglement séquentiel en tâche parallélisable. Firedancer utilise également des jeux d’instructions vectorisées tels qu’AVX512 et son extension IFMA (AVX512-IFMA). Ces jeux d’instructions permettent d’effectuer les opérations arithmétiques sur les corps de Galois expliquées précédemment, ce qui améliore la vitesse et l’efficacité.
L’implémentation de Firedancer accélérée par AVX512 est rapide. Sur un seul cœur de serveur Icelake à 2,3 GHz, ses performances par cycle d’horloge et par cœur sont plus de deux fois supérieures à celles de la démonstration présentée à Breakpoint en 2022. L’implémentation offre une utilisation à 100 % des voies vectorielles et une parallélisation massive des données. L’équipe Firedancer démontre une nouvelle fois avec brio qu’en raison des délais imposés par la vitesse de la lumière, il est bien plus facile d’effectuer des tâches indépendantes en parallèle que de les réaliser une par une, même avec du matériel personnalisé.
Exploiter les FPGA pour des communications réseau à haut débit
Les CPU peuvent effectuer ~30 000 vérifications de signatures par seconde et par cœur. Bien qu’économes en énergie, ils ne suffisent pas pour les opérations à grande échelle. Cette limite vient de leur mode de traitement séquentiel. Les GPU portent cette capacité à ~1 million de vérifications par seconde et par cœur. Toutefois, leur consommation électrique élevée d’environ ~300 W par unité et la latence inhérente au traitement par lots les pénalisent.
Les FPGA constituent une meilleure solution. Ils offrent le même débit que les GPU, mais avec une consommation électrique nettement inférieure, d’environ 50 W par FPGA. Leur latence est également inférieure aux dix millisecondes des GPU. Avec une latence de ~200 microsecondes, les FPGA offrent une solution beaucoup plus réactive pour le traitement en temps réel. Contrairement au traitement par lots des GPU, les FPGA de Firedancer traitent individuellement chaque transaction sous forme de flux. L’utilisation de FPGA par Firedancer permet d’atteindre un débit impressionnant de 8 millions de signatures par seconde, avec une enveloppe énergétique inférieure à 400 W pour 8 FPGA.
L’équipe a présenté le processus de vérification des signatures ED25519 de Firedancer lors de Breakpoint 2022. Ce processus comportait plusieurs étapes, notamment le calcul SHA-512 dans un pipeline RTL pur, ainsi que différentes vérifications et opérations dans un pipeline de processeur ECC-CPU personnalisé. En résumé, l’équipe Firedancer a écrit un compilateur et un assembleur pour son processeur personnalisé, repris le code Python de la RFC (Request for Comments), l’a exécuté avec des objets à opérateurs surchargés afin de générer du code machine, puis a placé ce code machine sur l’ECC-CPU.
Il est important de noter que Firedancer utilise un format d’accélérateur AWS afin d’équilibrer robustesse et connectivité réseau. Ce choix répond aux difficultés liées à la connectivité réseau directe, une fonctionnalité souvent limitée par les fournisseurs cloud. Firedancer assure ainsi une intégration fluide de ses capacités avancées malgré les contraintes des infrastructures cloud.
Il est essentiel de comprendre que différentes opérations nécessitent un espace physique concret, et pas seulement un espace conceptuel pour les données. Firedancer applique ce principe en disposant stratégiquement les composants physiques afin qu’ils soient proches et réutilisables. Cette configuration lui permet de maximiser l’efficacité de son FPGA et d’atteindre 8 millions de TPS avec un FPGA vieux de 7 ans installé dans une machine vieille de 8 ans.
Optimiser le codage Reed-Solomon pour les communications réseau
Le principal défi des communications réseau consiste à diffuser de nouvelles transactions dans le monde entier. La nature point à point d’Internet, la bande passante limitée et les problèmes de latence empêchent d’appliquer des approches traditionnelles telles que la diffusion directe sur le réseau. La distribution des données selon une structure en anneau ou en arbre résout partiellement ces problèmes, mais reste insuffisante, car des paquets de données peuvent être perdus pendant la transmission.
Le codage Reed-Solomon apporte une solution élégante à ces problèmes. Il introduit une redondance dans la transmission des données (c’est-à-dire des informations de parité) afin de récupérer les paquets perdus. Ce concept repose sur le principe selon lequel deux points définissent une droite et deux points quelconques de cette droite permettent de régénérer les points de données d’origine. En construisant un polynôme à partir des points de données et en distribuant différents points de cette fonction dans des paquets distincts, il est possible de reconstruire les données d’origine dès lors que le destinataire reçoit au moins deux paquets.
Nous construisons un polynôme, car l’utilisation de la formule traditionnelle des points d’une droite (y = mx + b) est lente sur le plan informatique. Pour accélérer le processus, Firedancer utilise les polynômes de Lagrange, une méthode spécialisée de construction polynomiale. Ils simplifient la création du polynôme nécessaire au codage Reed-Solomon. Ils transforment également le processus en un produit matrice-vecteur plus efficace qui fonctionne avec des polynômes d’ordre supérieur. Cette matrice est fortement structurée, avec des motifs qui se répètent de manière récursive, de sorte que sa première ligne suffit à la définir entièrement. Cette structure permet d’effectuer toutes les multiplications plus rapidement. Pour multiplier cette matrice, Firedancer utilise une approche O(n log n) présentée dans un article de 2016, l’approche théorique connue la plus rapide pour le codage Reed-Solomon. Elle permet de calculer les informations de parité plus efficacement que les méthodes traditionnelles :
- Plus de ~120 Gbit/s/cœur pour l’encodage RS
- Jusqu’à ~50 Gbit/s/cœur pour le décodage RS
- Ces mesures sont toutes comparées aux ~8 Gbit/s/cœur actuels pour l’encodage RS (rust-rse)
Grâce à cette approche optimisée du codage Reed-Solomon, Firedancer peut calculer la parité 14 fois plus vite que les méthodes traditionnelles. Il en résulte un processus d’encodage et de décodage des données rapide et fiable, essentiel au maintien d’un débit élevé et d’une faible latence à l’échelle mondiale.
Comment Firedancer est-il sécurisé ?
Opportunités
Tous les validateurs utilisent actuellement un logiciel fondé sur le client de validation d’origine. Firedancer peut améliorer la diversité des clients et de la chaîne d’approvisionnement de Solana s’il se distingue du client Solana Labs. Cela implique notamment d’utiliser des dépendances similaires et Rust pour développer son client.
Les clients de validation Solana Labs et Jito s’exécutent sous la forme d’un processus unique. Il est difficile de sécuriser une application monolithique une fois qu’elle est en production. Les validateurs utilisant ces clients devraient être arrêtés pour appliquer à la volée des mises à niveau de sécurité en Rust pur. Avec son nouveau client, l’équipe Firedancer peut bâtir dès le départ une architecture sécurisée.
Firedancer bénéficie également des enseignements tirés de l’expérience. Solana Labs a développé le client de validation dans un environnement de startup. Dans ce contexte effréné, Labs a dû avancer rapidement pour commercialiser son produit au plus vite. Cette approche a créé de mauvaises conditions pour les développements ultérieurs. L’équipe Firedancer peut étudier les choix de Labs et ceux des équipes d’autres blockchains, puis se demander ce qu’elle ferait différemment si elle pouvait développer un client de validation à partir de zéro.
Défis
Bien qu’il soit distinct du client Solana Labs, Firedancer doit reproduire fidèlement son comportement. Tout écart pose un problème de sécurité, car il pourrait introduire des bugs de consensus dus à une incompatibilité. Ce risque peut être atténué en incitant un certain pourcentage des fonds stakés à utiliser les deux clients et en maintenant Firedancer sous le seuil de 33 % du total des fonds stakés pendant une période prolongée. Quoi qu’il en soit, l’équipe Firedancer doit implémenter toutes les fonctionnalités du protocole, aussi difficiles soient-elles à implémenter correctement ou de façon sécurisée. Tout doit être aligné sur Firedancer. L’équipe ne peut donc pas développer le code de manière isolée et doit le confronter aux fonctionnalités du client Labs. L’absence de spécifications et de documentation aggrave le problème et oblige Firedancer à reprendre des constructions inefficaces du protocole.
L’équipe Firedaner doit également garder à l’esprit qu’elle développe son nouveau client en C. Le langage C ne fournit pas nativement les garanties de sécurité de la mémoire offertes par des langages comme Rust. L’un des principaux objectifs de la base de code de Firedancer consiste à réduire la fréquence et l’impact des vulnérabilités liées à la sécurité de la mémoire. Cet objectif exige une attention particulière, car Firedancer est un projet qui évolue rapidement. Firedancer doit trouver le moyen de maintenir son rythme de développement sans introduire de tels bugs. Le sandboxing de l’OS consiste à isoler les tiles de l’OS. Les tiles sont uniquement autorisées à accéder aux ressources et à effectuer les appels système nécessaires à leur tâche. Comme elles ont une fonction clairement définie et que l’équipe Firedancer a développé la majeure partie du code du client, les autorisations de chaque tile sont réduites conformément au principe du moindre privilège.
Mettre en œuvre une défense en profondeur dès la conception
Tout logiciel présentera un jour une vulnérabilité de sécurité. En partant du principe que les logiciels auront des bugs, Firedancer choisit de limiter l’impact potentiel de chaque vulnérabilité. Cette approche s’appelle la défense en profondeur. La défense en profondeur est une stratégie qui utilise différentes mesures de sécurité pour protéger un actif. Si un attaquant compromet une partie du système, des mesures supplémentaires empêchent la menace d’affecter l’ensemble de la pile. Firedancer est conçu pour intervenir entre l’apparition d’une vulnérabilité et son exploitation. Par exemple, il serait difficile pour un attaquant d’exploiter une vulnérabilité liée à la sécurité de la mémoire.
En effet, la prévention de ce type d’attaque est un problème largement étudié. Les nombreuses recherches consacrées à la sécurité de la mémoire en C ont produit tout un arsenal de techniques de renforcement et de fonctionnalités de compilation que l’équipe utilise pour Firedancer. Même si un attaquant parvenait à contourner les meilleures pratiques du secteur, l’exploitation de la faille aurait du mal à compromettre le système. Cela tient à l’isolation des tiles et au sandboxing de l’OS.
L’isolation des tiles découle de l’architecture parallèle de Firedancer. Chaque tile a une fonction unique et clairement définie, car elle exécute son propre processus Linux. Par exemple, une tile QUIC traite le trafic QUIC entrant et transmet les transactions encapsulées à la tile de vérification. Celle-ci se charge ensuite de vérifier les signatures. La communication entre les tiles QUIC et de vérification passe par une interface de mémoire partagée (c’est-à-dire que les processus Linux peuvent échanger des données). Cette interface de mémoire partagée entre deux tiles sert de limite d’isolation. Si la tile QUIC présentait un bug permettant à un attaquant d’exécuter du code arbitraire lors du traitement d’un paquet QUIC malveillant, aucune autre tile ne serait affectée. Dans un processus monolithique, le système serait immédiatement compromis. Un attaquant pourrait nuire à l’ensemble du réseau s’il exploitait cette vulnérabilité sur plusieurs validateurs. Il pourrait dégrader les performances de la tile QUIC, mais la conception de Firedancer limiterait son action à cette seule tile.
Le sandboxing de l’OS consiste à isoler les tiles de l’OS. Les tiles sont uniquement autorisées à accéder aux ressources et à effectuer les appels système nécessaires à leur tâche. Comme elles ont une fonction clairement définie et que l’équipe Firedancer a développé la quasi-totalité du code, les autorisations de chaque tile sont réduites conformément au principe du moindre privilège. Les tiles sont placées dans leurs propres espaces de noms Linux, ce qui leur donne une vue limitée du système. Cette vue restreinte empêche une tile d’accéder à la majeure partie du système de fichiers, au réseau et à tout autre processus exécuté sur le même système. Les espaces de noms créent une limite axée sur la sécurité. Toutefois, un attaquant disposant d’un exploit du kernel permettant une élévation de privilèges peut encore la contourner. L’interface des appels système constitue le dernier vecteur d’attaque du kernel accessible depuis les tiles. Pour s’en protéger, Firedancer utilise seccomp-BPF afin de filtrer les appels système avant leur traitement par le kernel. Le client peut limiter les tiles à un groupe précis d’appels système. Dans certains cas, les paramètres des appels système peuvent également être filtrés. C’est important, car Firedancer peut ainsi garantir que les appels système de lecture et d’écriture agissent uniquement sur des descripteurs de fichiers précis.
Mettre en œuvre un programme de sécurité intégré
Firedancer est conçu autour d’un programme de sécurité complet, intégré à chaque étape de son développement. Le programme de sécurité du client repose sur une collaboration continue entre les équipes de développement et de sécurité, établissant ainsi une nouvelle référence pour la sécurisation des technologies blockchain.
Le processus commence par une infrastructure de fuzzing en libre-service. Pour rappel, le fuzzing est une technique qui détecte automatiquement les plantages ou les erreurs révélant des vulnérabilités. Pour cela, chaque composant acceptant des entrées utilisateur non fiables est soumis à des tests intensifs, notamment l’interface P2P (analyseurs) et la machine virtuelle SBPF. OSS-Fuzz maintient une couverture de fuzzing continue au fil des modifications du code. L’équipe de sécurité a également configuré une instance dédiée de ClusterFuzzer pour un fuzzing continu guidé par la couverture. Les développeurs et les ingénieurs en sécurité contribuent aussi à des bancs de fuzzing (c’est-à-dire des versions spéciales de tests unitaires pour les composants critiques en matière de sécurité). Les développeurs peuvent également ajouter de nouveaux tests de fuzzing, qui sont automatiquement récupérés et exécutés. L’objectif est de soumettre toutes les parties à un fuzzing intensif avant leur passage à l’étape suivante.
Les revues de code internes permettent d’identifier les bugs que les outils n’ont pas détectés. À ce stade, l’accent est mis sur les composants à haut risque et à fort impact. Cette étape constitue un mécanisme de rétroaction qui alimente le reste du programme de sécurité. L’équipe applique tous les enseignements tirés et s’appuie sur ces revues pour améliorer la couverture du fuzzing, ajouter de nouvelles vérifications d’analyse statique pour certaines catégories de bugs et même effectuer d’importantes refactorisations afin d’éliminer dès la conception les vecteurs d’attaque complexes. Des experts reconnus du secteur compléteront ces revues internes par des audits de sécurité externes, parallèlement à un programme actif de bug bounty, avant comme après le lancement.
Firedancer a également fait l’objet de tests de charge approfondis sur différents réseaux de test. Ces réseaux seront soumis à des attaques et à des défaillances telles que la duplication de nœuds, la panne de liaisons réseau, l’inondation de paquets et les violations du consensus. Ils supportent des charges nettement supérieures à tout scénario réaliste sur le mainnet.
Cela nous amène donc à la question suivante : où en est Firedancer aujourd’hui ?
Où en est Firedancer et qu’est-ce que Frankendancer ?
L’équipe Firedancer développe Firedancer de manière progressive afin de modulariser le client de validation. Cette démarche correspond à ses objectifs de documentation et de standardisation. Elle garantit que Firedancer reste à jour avec les dernières évolutions de Solana. C’est ainsi qu’est né Frankendancer. Frankendancer est un modèle de client hybride dans lequel l’équipe Firedancer intègre les composants qu’elle a développés à l’infrastructure existante du client de validation. Ce processus de développement permet d’améliorer et de tester progressivement les nouvelles fonctionnalités.
Frankendancer revient à placer une voiture de sport au milieu de la circulation. Les performances augmenteront à mesure que de nouveaux composants seront développés et que les goulots d’étranglement seront éliminés. Ce processus de développement modulaire crée un environnement de validation personnalisable et flexible. Les développeurs peuvent ainsi modifier ou remplacer certains composants de leur client de validation en fonction de leurs besoins.
Qu’est-ce qui fonctionne réellement ?
Frankendancer implémente toutes les fonctionnalités réseau d’un validateur Solana :
- Entrant : QUIC, TPU, Sigverify, Dedup
- Sortant : regroupement des blocs, création/signature/envoi des shreds (Turbine)
Frankendancer utilise le code réseau C haute performance de Firedancer au-dessus du runtime et du code de consensus Rust de Solana Labs.
L’architecture de Frankendancer est conçue pour optimiser le matériel haut de gamme. Bien qu’elle prenne en charge les hôtes cloud d’entrée de gamme exécutant des systèmes Linux standard, l’équipe Firedancer optimise Frankendancer pour les serveurs dotés d’un grand nombre de cœurs. À long terme, l’objectif est d’exploiter le matériel déjà disponible dans le cloud afin d’améliorer l’efficacité et les performances. Le client prend en charge plusieurs connexions simultanées, l’accélération matérielle, l’orientation aléatoire des flux pour répartir la charge (c’est-à-dire assurer une distribution uniforme du trafic réseau) et de nombreuses limites entre les processus pour renforcer la sécurité entre les composants.
L’efficacité technique est au cœur de Frankendancer. Le système évite les allocations de mémoire et les opérations atomiques sur le chemin critique, toutes les allocations étant optimisées pour NUMA lors de l’initialisation. Cette conception garantit une efficacité et des performances maximales. En outre, la possibilité d’inspecter les composants du système à distance et de manière asynchrone, associée à la souplesse de gestion des tiles (démarrage, arrêt et redémarrage asynchrones), renforce la robustesse et l’adaptabilité du système.
Quelles sont ses performances ?
Frankendancer peut traiter 1 000 000 de transactions par seconde (TPS) et par tile du côté du trafic réseau entrant. Ces performances évoluent linéairement avec le nombre de cœurs utilisés, puisqu’un cœur CPU est affecté à chaque tile. Frankendancer a réalisé cette prouesse en utilisant seulement quatre cœurs et en saturant une carte d’interface réseau (NIC) de 25 Gbit/s.
Frankendancer a considérablement amélioré les opérations réseau sortantes grâce à ses optimisations de Turbine. Le matériel standard actuel d’un nœud atteint 6 Gbit/s par tile. Cela inclut d’importants gains de vitesse pour le shredding (c’est-à-dire la manière dont les données de bloc sont divisées et envoyées aux validateurs sur le réseau). Par rapport aux nœuds Solana standard actuels, Frankendancer augmente la vitesse de shredding de ~22 % sans arbres de Merkle et la double presque avec ces arbres. Il s’agit d’une amélioration considérable des performances actuelles des validateurs en matière de propagation des blocs et d’ingestion des transactions.
Les performances réseau de Firedancer montrent qu’il a atteint la limite du matériel. Il a obtenu les performances maximales possibles avec le matériel standard actuel des validateurs. Il s’agit d’une étape technique majeure, qui démontre la capacité du client à gérer efficacement des charges de travail extrêmes.
Frankendancer est opérationnel sur le testnet
Frankendancer est actuellement staké, vote et produit des blocs sur le testnet. Il coexiste de manière compatible avec ~2 900 autres validateurs Solana Labs et Jito. Ce déploiement en conditions réelles démontre les solides performances de Firedancer sur du matériel grand public. Il s’exécute actuellement sur un serveur Equinix Metal m3.large.x86 équipé d’un CPU AMD EPYC 7513. De nombreux autres validateurs utilisent le même type de serveur. Il offre une solution économique avec une tarification à la demande qui varie selon l’emplacement. Les tarifs vont de 3,10 $ à 4,65 $ de l’heure.
La progression de Firedancer vers son lancement sur le mainnet ouvre plusieurs possibilités pour le matériel des nœuds :
- Le matériel actuel des validateurs peut offrir une capacité de traitement bien supérieure par nœud
- L’efficacité de Firedancer permet aux validateurs d’utiliser du matériel plus abordable et moins puissant tout en maintenant des niveaux de performances similaires
- La conception de Firedancer lui permet de tirer parti des progrès du matériel et de la bande passante
Ces avancées, ainsi que d’autres initiatives telles que Wiredancer (c’est-à-dire les expérimentations de l’équipe Firedancer en matière d’accélération matérielle) et un Runtime/SVM modulaire basé sur Rust, font de Firedancer une solution tournée vers l’avenir.
Les progrès de Firedancer ouvrent également la voie à la possibilité pour les validateurs d’exécuter le client Solana Labs en parallèle de Firedancer, selon un processus appelé side-caring. Cette approche pourrait maximiser la disponibilité du réseau en combinant les points forts des deux clients et en limitant l’impact potentiel sur l’ensemble du réseau des problèmes rencontrés par l’un ou l’autre. Elle alimente également les spéculations sur la possibilité que des projets comme Jito envisagent de forker Firedancer. Cela pourrait optimiser davantage l’extraction de MEV et l’efficacité du traitement des transactions. Seul l’avenir nous le dira.
Conclusion
Les développeurs conçoivent généralement les opérations comme occupant un espace de données plutôt qu’un espace physique. Avec la vitesse de la lumière comme contrainte naturelle, cette hypothèse conduit à des systèmes lents qui n’optimisent pas correctement leur matériel. Dans un environnement hautement concurrentiel et hostile, nous devons éviter de simplement ajouter du matériel à Solana en espérant de meilleures performances. Nous devons optimiser. Firedancer révolutionne la structure et le fonctionnement attendu des clients de validation. En développant un client de validation fiable, hautement modulaire et performant, l’équipe Firedancer prépare Solana à une adoption massive.
Que vous soyez un développeur débutant ou un utilisateur ordinaire de Solana, il est essentiel de comprendre Firedancer et son importance. Cette prouesse technologique améliore encore la blockchain la plus rapide et la plus performante actuellement disponible sur le marché. Solana est conçue comme une machine à états globale à haut débit et faible latence. Firedancer représente une avancée majeure vers la réalisation parfaite de ces objectifs.
Si vous avez lu jusqu’ici, merci, anon ! Saisissez votre adresse e-mail ci-dessous pour ne manquer aucune actualité concernant les nouveautés de Solana. Vous souhaitez aller plus loin ? Rejoignez notre Discord pour commencer dès aujourd’hui à construire l’avenir sur la blockchain la plus performante.
Ressources supplémentaires / Pour aller plus loin
- Site web de Jump
- Dépôt GitHub de Firedancer
- Breakpoint 2023 : actualités de Firedancer
- Breakpoint 2023 : sécuriser Firedancer
- Breakpoint 2023 : codage Reed-Solomon rapide pour les communications réseau
- Breakpoint 2023 : un FPGA fonctionnant à 8 millions de TPS
- Jalon technique fd_quic de Firedancer
- Mises à niveau du réseau Solana
Annexe
Introduction au matériel informatique et aux réseaux
Un ordinateur est une machine qui peut être programmée pour exécuter automatiquement des séquences d’opérations arithmétiques ou logiques. Ces opérations vont de l’automatisation de calculs élémentaires au traitement complexe de données. Fondamentalement, un ordinateur combine des composants matériels et logiciels pour exécuter des instructions et gérer des données. Le matériel comprend les composants physiques, tandis que les logiciels regroupent les programmes et systèmes d’exploitation qui indiquent au matériel comment fonctionner.
Un calcul utile mobilise généralement quatre ressources : la puissance de calcul, la mémoire, le stockage sur disque et le réseau. La partie calcul, principalement assurée par les CPU, les GPU et éventuellement les FPGA, est extrêmement rapide et peut effectuer des milliards d’opérations par seconde. L’accès à la RAM est généralement plus lent que l’exécution d’un calcul par le CPU. Le stockage sur disque constitue une solution de conservation des données à long terme utile aux calculs. Cependant, l’accès aux données des disques SSD (SSD) et des disques durs (HDD) est beaucoup plus lent que les opérations du CPU. Les SSD sont souvent des milliers de fois plus lents, et les HDD des dizaines de milliers de fois plus lents. De plus, le réseau, notamment Internet et les réseaux locaux, est le plus lent. Il peut être plus d’un million de fois plus lent que le CPU.
Comprendre ces différences de vitesse est essentiel pour saisir les principes de conception et les considérations d’efficacité des applications de calcul haute performance telles que Firedancer. La vitesse de calcul du CPU sert de référence, tandis que l’accès à la mémoire, au stockage sur disque et au réseau ajoute chaque fois un niveau de délai, dans cet ordre décroissant de vitesse.
Unité centrale de traitement (CPU)
Le CPU, ou unité centrale de traitement, est la pierre angulaire du fonctionnement d’un ordinateur : c’est le cerveau de la machine. Le CPU exécute les instructions logicielles, effectue des calculs et prend des décisions en fonction des entrées qu’il reçoit. Il traite des signaux binaires, qui sont des séquences de zéros et de uns. Chaque série unique de codes binaires correspond à une instruction précise que le CPU interprète et exécute. Ces instructions sont traitées séquentiellement, le CPU terminant une opération avant de passer à la suivante. Ce traitement séquentiel des instructions est fondamental pour le rôle du CPU et détermine la façon dont il effectue des calculs complexes et prend des décisions en fonction des entrées reçues.
Les CPU modernes sont souvent multicœurs. Cela signifie qu’ils contiennent plusieurs unités de traitement, appelées cœurs, au sein d’une même puce. Chaque cœur peut exécuter des instructions indépendamment, permettant ainsi le traitement parallèle des tâches. L’architecture multicœur améliore la capacité du CPU à gérer simultanément plusieurs opérations, ce qui accroît considérablement les performances globales. Il est toutefois important de noter que les opérations sont toujours traitées séquentiellement au sein de chaque cœur. Les CPU sont donc bien adaptés aux tâches complexes et séquentielles, mais peu efficaces pour de grands volumes de tâches parallèles plus simples.
Les CPU disposent également de mémoires caches, de petites unités de mémoire à haute vitesse intégrées au CPU. Ces caches stockent les données et instructions fréquemment consultées, permettant de les récupérer plus rapidement qu’en les chargeant depuis la RAM. Il existe généralement plusieurs niveaux de cache (L1, L2, L3 et parfois L4), dont les tailles et les vitesses varient. Le cache L1, le plus petit et le plus rapide, est consulté en premier. Si les données requises ne s’y trouvent pas, le CPU vérifie le cache L2, plus grand et légèrement plus lent, et ainsi de suite. Ce système hiérarchique de caches réduit le temps d’attente du CPU pour les données provenant de la RAM et améliore la vitesse globale de traitement. L’utilisation efficace du cache a des implications majeures pour une application telle que Firedancer, où la distance entre le CPU et la RAM peut nuire aux performances. Ce point est particulièrement pertinent pour nos explications sur la vitesse de la lumière et l’utilisation des FPGA.
À titre indicatif, le terme « x86 » désigne une famille de CPU reposant sur une architecture particulière initialement développée par Intel. Cette architecture est connue pour sa compatibilité avec un large éventail de logiciels, car la plupart des ordinateurs de bureau et portables vendus reposent sur la famille d’architectures x86.
Processeur graphique (GPU)
Le GPU est un processeur spécialisé initialement développé pour accélérer le rendu d’images et de vidéos en infographie. Sa fonction principale consiste à gérer et améliorer les performances graphiques, en particulier pour les tâches exigeant des visuels haute résolution et des calculs graphiques complexes, comme les jeux vidéo ou la modélisation 3D.
Au fil du temps, le GPU a évolué au-delà de sa fonction initiale. Grâce à leur architecture, les GPU sont devenus indispensables à un éventail plus large de tâches de traitement des données. Leur capacité à effectuer efficacement des traitements parallèles les rend adaptés aux applications qui doivent gérer simultanément de grands ensembles de données. Dans la technologie blockchain, les GPU sont largement utilisés pour le minage de cryptomonnaies. Ils excellent dans ce rôle, car ils peuvent traiter des charges parallèles de calculs cryptographiques plus efficacement qu’un CPU.
Mémoire vive (RAM)
La RAM est la mémoire à court terme d’un ordinateur. Elle stocke les données en cours d’utilisation ou de traitement. C’est là que le CPU « mémorise » ce sur quoi il travaille et conserve les informations pertinentes pour y accéder et les traiter rapidement.
La RAM à code correcteur d’erreurs (ECC) peut détecter et corriger les types courants de corruption interne des données. Cette fonctionnalité est essentielle dans les environnements où l’exactitude des données est importante, comme le calcul scientifique, les transactions financières ou les nœuds blockchain. La RAM ECC peut identifier et corriger automatiquement les erreurs mineures dans les données qu’elle stocke. Ce processus de correction des erreurs est assuré par du matériel supplémentaire dans les modules de RAM, qui vérifie les données stockées.
La RAM non-ECC est le type de mémoire le plus couramment utilisé dans les ordinateurs standards et les appareils grand public. Bien qu’elle ne dispose pas des capacités de correction d’erreurs de la RAM ECC, elle est généralement plus rapide et moins chère. La RAM non-ECC est privilégiée pour un usage général en raison de son rapport coût-efficacité et du risque relativement faible d’erreurs de données dans l’informatique de bureau standard.
Stockage sur disque
Le stockage sur disque assure la conservation à long terme des données, même lorsque l’ordinateur est éteint. Il existe deux principaux types de stockage sur disque : les disques durs (HDD) et les disques SSD.
Les HDD sont des disques d’ancienne génération qui stockent les données sur des disques magnétiques appelés plateaux. Ces plateaux sont associés à des têtes magnétiques, généralement fixées à un bras actionneur mobile. Une tête de lecture/écriture placée sur ce bras accède aux données pendant la rotation du disque. La nature mécanique des HDD, avec leurs disques rotatifs et leurs têtes mobiles, les rend relativement plus lents que les SSD. Ils offrent toutefois une plus grande capacité de stockage à moindre coût. Ils constituent donc une solution économique pour le stockage de masse.
Les SSD, quant à eux, utilisent de la mémoire flash pour stocker les données. La mémoire flash est une solution de stockage électronique non volatile qui peut être effacée et reprogrammée. Contrairement aux HDD, l’utilisation de mémoire flash n’implique aucune pièce mobile. Les données sont stockées dans des puces de mémoire flash interconnectées. Les SSD sont plus rapides que les HDD, car ils peuvent accéder instantanément aux données sans attendre la rotation d’un disque ni le positionnement d’une tête de lecture/écriture. Cette rapidité fait des SSD un excellent choix pour les applications où la récupération rapide des données est cruciale. Elle s’accompagne toutefois d’un coût par gigaoctet supérieur à celui des HDD.
Il existe également des SSD NVMe (Non-Volatile Memory Express). Ces SSD sont conçus pour exploiter leur potentiel de haute vitesse grâce au bus Peripheral Component Interconnect Express (PCIe) d’un ordinateur. Les disques NVMe offrent des vitesses nettement supérieures et une latence plus faible que les SSD traditionnels. Ils conviennent parfaitement aux charges de travail intensives, comme le trading haute fréquence et les applications blockchain, où le traitement et la récupération rapides des données sont essentiels. Bien que les NVMe soient plus onéreux, ils commencent à s’imposer comme la norme du calcul haute performance.
Carte mère
Source : Schéma d’une Gigabyte X570 Elite tiré d’une publication Reddit sur r/buildapc
La carte mère d’un ordinateur est un grand circuit imprimé qui interconnecte les composants de l’ordinateur et facilite leur communication. Ces composants comprennent le CPU, le GPU, la RAM, les périphériques de stockage et les périphériques externes tels que les claviers et les souris.
La carte mère est le centre névralgique du système. Elle garantit que chaque composant peut communiquer efficacement avec les autres. Elle joue également un rôle essentiel dans la distribution de l’alimentation en acheminant l’électricité du bloc d’alimentation vers chaque composant principal. La carte mère garantit que chaque composant reçoit l’énergie nécessaire à son fonctionnement.
La carte mère gère le flux de données au sein du système. Elle supervise l’acheminement des données du CPU vers la RAM pour leur traitement, de la RAM vers les périphériques de stockage pour leur enregistrement et du GPU vers les sorties d’affichage pour le rendu visuel. En outre, la carte mère héberge également le BIOS (Basic Input/Output System) du système. Le BIOS joue un rôle essentiel dans le contrôle et la surveillance du système. Il initialise et teste le matériel d’un ordinateur au démarrage. Il surveille également l’état du système, notamment la température, la tension et la vitesse des ventilateurs.
Dans le contexte de la conception de Firedancer, l’architecture de la carte mère joue un rôle central. La proximité du CPU avec la RAM a un impact considérable sur les performances, car une distance plus courte entre eux augmente la vitesse de transfert des données. Cette distance est essentielle pour les applications comme Firedancer, qui exigent un débit élevé et une faible latence. C’est pourquoi une architecture tenant compte de NUMA et l’utilisation potentielle de FPGA répondent aux besoins de Firedancer en matière d’optimisation de l’allocation de mémoire et de l’efficacité du traitement. Nous expliquerons plus loin dans cet article ce que signifie la prise en compte de NUMA et ce que sont les FPGA.
Systèmes d’exploitation, machines virtuelles et optimisations au niveau du noyau
Un système d’exploitation (OS) est le logiciel central qui gère le matériel et les logiciels d’un ordinateur. Il joue un rôle d’intermédiaire en facilitant les interactions entre l’utilisateur et le matériel de l’ordinateur. Il fournit une interface permettant aux utilisateurs d’interagir avec le système, et alloue et gère les ressources destinées aux différentes applications. Windows, macOS et Linux en sont des exemples populaires.
Le noyau est au cœur de chaque système d’exploitation. Il s’agit d’un composant essentiel qui interagit directement avec le matériel du système. Le noyau contrôle intégralement tous les éléments du système. Il gère l’allocation de mémoire, la planification des processus et les requêtes d’entrée/sortie. En opérant à ce niveau bas, le noyau joue un rôle essentiel dans les performances et la stabilité du système.
Les appels système (syscalls) servent d’interface entre les applications utilisateur et le noyau. Lorsqu’une application doit effectuer une opération nécessitant l’accès à une ressource système, par exemple lire un fichier ou envoyer des données sur le réseau, elle émet un syscall. Le noyau effectue alors l’opération demandée pour le compte de l’application. Ce mécanisme garantit un accès contrôlé aux ressources système afin de préserver la sécurité et la stabilité du système.
Les machines virtuelles (VM) sont des émulations logicielles d’ordinateurs physiques. Elles reproduisent toutes les fonctionnalités d’un ordinateur physique dans un environnement isolé, tout en s’exécutant sur un hyperviseur, c’est-à-dire un type de logiciel qui crée et gère des environnements virtuels sur une machine hôte. Les VM offrent les avantages d’une sécurité assurée par l’isolation, d’une utilisation efficace des ressources et d’une grande flexibilité pour les tests et le développement.
La compréhension de ces concepts est essentielle dans le contexte de Firedancer. Firedancer emploie plusieurs optimisations au niveau du noyau pour améliorer les performances :
- Allocation statique importante : Firedancer réduit les allocations dynamiques de mémoire grâce à de grandes allocations statiques, c’est-à-dire des allocations de mémoire partagée que d’autres processus peuvent utiliser. La mémoire est ici allouée une seule fois, puis réutilisée, ce qui réduit la surcharge liée aux allocations et libérations fréquentes.
- Contournement des bibliothèques standards : les fonctions des bibliothèques standards ajoutent souvent des couches d’abstraction supplémentaires et peuvent être moins efficaces pour certaines opérations. Firedancer contourne ces bibliothèques standards et effectue directement des syscalls. Nous approfondirons ce sujet lorsque nous aborderons l’architecture en tuiles de Firedancer et la manière dont elle optimise ses performances réseau.
Firedancer tente autant que possible d’éviter les syscalls et les interactions avec l’OS, car ces opérations ralentissent considérablement les tâches.
Trafic entrant et sortant
Les termes trafic entrant et trafic sortant décrivent le flux de données qui entre dans un système informatique ou un réseau, ou qui en sort.
Le trafic entrant désigne l’entrée de données dans un système. Il s’agit d’un terme général qui peut couvrir diverses activités, comme la réception de données depuis Internet, l’acceptation de saisies utilisateur ou la collecte d’informations provenant de capteurs dans des appareils IoT (Internet des objets). Pour les systèmes en réseau tels que les serveurs ou les blockchains, le trafic entrant comprend des tâches essentielles comme la réception de demandes de transaction, de requêtes utilisateur ou de flux de données entrants qui doivent être traités ou stockés. Une gestion efficace des données entrantes est essentielle à la réactivité et au bon fonctionnement du système.
Le trafic sortant désigne les données qui quittent un système. Cela comprend l’envoi d’informations en ligne, la génération de réponses aux requêtes des utilisateurs ou la transmission de données traitées à d’autres systèmes. Pour les systèmes en réseau, le trafic sortant comprend l’envoi de transactions validées, la diffusion de mises à jour de la blockchain ou l’envoi de données vers des emplacements de stockage externes. Une bonne gestion des données sortantes est essentielle pour diffuser correctement les informations et garantir que le système communique efficacement avec les autres parties du réseau.
Pipelines et parallélisme des données
Imaginez un pipeline comme une chaîne de montage dans une usine. Il décompose un processus complexe en étapes séquentielles plus petites. Chaque étape du pipeline effectue une opération particulière. Cette approche est très efficace pour les tâches de traitement répétitives ou continues, tout comme une blockchain traite continuellement des transactions.
Le parallélisme des données adopte une approche différente en traitant plusieurs éléments simultanément, mais indépendamment. C’est comme si l’usine disposait de plusieurs chaînes de montage pour traiter les données. Cette méthode est efficace pour les tâches qui peuvent être décomposées en sous-tâches plus petites. Pour les blockchains, et plus particulièrement dans des systèmes comme Firedancer, le parallélisme des données est essentiel pour gérer simultanément des transactions ou des tâches de traitement des données. Les capacités de traitement parallèle de Firedancer maximisent le débit de calcul et réduisent les temps de traitement.
Imaginez chaque étape du pipeline comme un poste de travail individuel dans une usine. Chaque poste peut fonctionner de manière indépendante et simultanée. Ainsi, pendant qu’une étape traite une partie des données, l’étape suivante peut travailler en même temps sur une autre partie. Cette approche permet à plusieurs étapes du pipeline d’être actives simultanément, ce qui augmente considérablement le débit. Firedancer associe l’efficacité séquentielle du pipeline à la puissance de traitement simultané du parallélisme pour traiter de grands volumes de transactions.
Réseau de portes programmables (FPGA)
Les réseaux de portes programmables (FPGA) sont des circuits intégrés polyvalents qui peuvent être programmés ou reconfigurés après leur fabrication. Ces circuits offrent un niveau d’adaptabilité absent des composants matériels traditionnels. Ils sont constitués d’une vaste grille de blocs logiques programmables et interconnectés, chacun pouvant exécuter diverses fonctions numériques. Cette conception permet aux FPGA d’offrir une grande flexibilité et une efficacité élevée dans les applications où la vitesse, le traitement parallèle et l’adaptabilité sont primordiaux.
Un FPGA classique se compose de minuscules éléments programmables, tous reliés par des connexions programmables. Ce réseau complexe d’éléments et de connexions permet aux utilisateurs de programmer différentes régions de la puce pour qu’elles exécutent des tâches précises. Il crée ainsi un environnement de traitement entièrement personnalisé.
Les FPGA excellent dans le traitement parallèle en utilisant simultanément ces minuscules éléments programmables. Leur structure facilite la mise en pipeline, dans laquelle les données traversent continuellement les différentes étapes de traitement. Un pipeline bien conçu dissocie le débit du système de sa latence. Même si ce pipeline peut mettre plus de temps qu’un CPU classique à produire un résultat, le système peut gérer simultanément plusieurs flux de données en entrée. La latence de chaque opération a peu d’incidence sur le flux global des données, à l’image de l’eau circulant dans un tuyau.
Dans le contexte de Firedancer, les FPGA offrent un avantage considérable. Ils peuvent connecter directement les pipelines de données aux réseaux. Les FPGA sont plus efficaces pour gérer le trafic réseau que les configurations traditionnelles, dans lesquelles les GPU dépendent des CPU pour déplacer les données. Cette connectivité directe et la possibilité de créer des solutions de traitement personnalisées, notamment en intégrant des processeurs logiciels à la matrice FPGA, les rendent indispensables au développement d’un client de validation haute performance.
Articles associés
Abonnez-vous à Helius
Suivez les dernières actualités du développement sur Solana et recevez une notification à chaque publication


