2 points par GN⁺ 2026-01-08 | Aucun commentaire pour le moment. | Partager sur WhatsApp
  • Une validation expérimentale du déséquilibre entre les performances d’I/O et la vitesse de traitement du CPU récemment discuté montre qu’en pratique, le CPU reste la principale contrainte
  • La vitesse de lecture séquentielle atteint 1,6 Go/s avec un cache froid et 12,8 Go/s avec un cache chaud, mais le calcul de fréquence des mots sur un seul thread reste autour de 278 Mo/s
  • La structure en branches du code empêche la vectorisation, et même une simple optimisation de conversion en minuscules n’améliore les performances qu’à environ 330 Mo/s
  • Même la commande wc -w ne atteint que 245 Mo/s, ce qui confirme que le calcul CPU et le traitement des branches, plutôt que le disque, constituent le goulot d’étranglement
  • Une vectorisation manuelle basée sur AVX2 a permis d’atteindre 1,45 Go/s, mais cela ne représente encore qu’environ 11 % de la vitesse de lecture séquentielle, ce qui prouve que le CPU, et non l’I/O, est le goulot d’étranglement

Comparaison entre vitesse d’I/O et performances CPU

  • En suivant l’affirmation de Ben Hoyt, une expérience a été menée pour vérifier si la récente hausse de la vitesse de lecture séquentielle avait dépassé la stagnation des performances CPU
    • Mesuré de la même manière, le résultat est de 1,6 Go/s avec cache froid et 12,8 Go/s avec cache chaud
  • Pourtant, le calcul de fréquence des mots sur un seul thread n’atteint que 278 Mo/s
    • Même avec un cache chaud, cela représente environ un cinquième de la vitesse de lecture du disque

Expérience de calcul de fréquence des mots en C

  • Avec GCC 12, optimized.c a été compilé avec les options -O3 -march=native, puis exécuté sur un fichier d’entrée de 425 Mo
    • Résultat : 1,525 seconde, soit un débit de 278 Mo/s
  • Les multiples branches dans le code et les sorties anticipées empêchent les optimisations de vectorisation du compilateur
    • Après avoir déplacé la logique de conversion en minuscules hors de la boucle, le débit est monté à 330 Mo/s
    • Avec Clang, la vectorisation est mieux réalisée

Comparaison avec un simple comptage de mots (wc -w)

  • Exécution de la commande wc -w, qui compte seulement le nombre de mots au lieu de calculer leur fréquence
    • Résultat : 245,2 Mo/s, plus lent que prévu
  • wc traite divers caractères d’espacement comme ' ', '\n', '\t', ainsi que des caractères dépendants de la locale
    • Il effectue donc davantage d’opérations qu’un code qui ne distingue que l’espace simple

Tentative de vectorisation basée sur AVX2

  • Mise en œuvre d’une vectorisation avec le jeu d’instructions AVX2 en exploitant les fonctionnalités des CPU récents
    • Utilisation de registres 256 bits et alignement des données sur 32 bits
    • Utilisation de l’instruction VPCMPEQB pour comparer les caractères d’espacement
  • Détection des frontières de mots à l’aide d’un masque de bits (PMOVMSKB) et de l’instruction Find First Set (ffs)
    • Inspiré de l’implémentation de strlen dans Cosmopolitan libc

Résultats de performance et conclusion

  • Le code vectorisé manuellement (wc-avx2) atteint un débit de 1,45 Go/s
    • Vérification effectuée avec le même résultat que wc -w (82,113,300 mots)
  • Même avec un cache froid, le temps de calcul en mode user reste dominant
    • Cela confirme que le calcul CPU est le goulot d’étranglement, plus encore que l’I/O disque
  • Globalement, la vitesse du disque est suffisante, mais le traitement des branches et les calculs de hachage côté CPU restent les facteurs limitants
  • Le code et les résultats expérimentaux sont publiés sur GitHub (haampie/wc-avx2)

Aucun commentaire pour le moment.

Aucun commentaire pour le moment.