14 points par GN⁺ 2024-11-08 | 3 commentaires | Partager sur WhatsApp
  • recall est un service qui fournit des bots de réunion à des centaines d’entreprises et exploite une infrastructure à grande échelle sur AWS
  • pour proposer un service rentable, l’entreprise cherche à tirer le maximum des performances matérielles
  • ces dernières années, la disponibilité des GPU chez les fournisseurs cloud ayant été instable, le traitement vidéo a été effectué sur CPU plutôt que sur GPU
  • en profilant les bots utilisant Chromium headless, ils ont constaté que la majeure partie du temps CPU n’était pas consommée par le traitement vidéo (encodage/décodage), mais par les fonctions de copie mémoire __memmove_avx_unaligned_erms et __memcpy_avx_unaligned_erms
    • memmove et memcpy sont des fonctions de copie de blocs mémoire de la bibliothèque standard C (glibc)
    • memmove gère quelques cas particuliers liés à la copie de zones mémoire qui se chevauchent, mais les deux peuvent être classées comme des fonctions de « copie mémoire »
    • le suffixe avx_unaligned_erms indique une optimisation pour les systèmes prenant en charge les Advanced Vector Extensions (AVX), y compris pour les accès mémoire non alignés
    • erms signifie Enhanced REP MOVSB/STOSB, une optimisation des processeurs Intel récents pour accélérer les déplacements mémoire. On peut le comprendre comme « une implémentation plus rapide pour certains processeurs »
  • le profilage a montré que ces fonctions étaient le plus souvent appelées par le client WebSocket Python qui recevait les données
    • l’implémentation WebSocket de Chromium, qui envoyait les données, arrivait juste après en nombre d’appels

Les problèmes de WebSocket

  • un serveur WebSocket local était utilisé pour transmettre les données vidéo brutes depuis l’environnement JS de Chromium vers l’encodeur
  • un flux vidéo brut en 1080p à 30 fps exige une bande passante élevée, de plus de 93 MB/s
  • l’usage de WebSocket entraînait un coût de calcul important, principalement à cause de la fragmentation et du masquage
    • fragmentation : l’implémentation WebSocket de Chromium fragmente les messages de plus de 131 KB en plusieurs frames. Une frame vidéo brute de plus de 3 MB est ainsi découpée en plus de 24 frames distinctes pour être transmise
    • masquage : pour des raisons de sécurité, WebSocket masque toutes les frames envoyées du client vers le serveur. Sur de gros volumes de données dépassant 100 MB/s, cela représente un surcoût significatif

Recherche d’alternatives

  • avec les API du navigateur, il était difficile de mettre en place quelque chose de bien plus performant que WebSocket, ils ont donc décidé de forker Chromium pour y implémenter une fonctionnalité personnalisée
  • trois alternatives ont été envisagées : raw TCP/IP, Unix Domain Socket, Shared Memory
    • TCP/IP : cela évite les problèmes de fragmentation/masquage de WebSocket, mais la taille maximale des paquets reste faible, donc le problème de fragmentation subsiste. Il y a aussi le surcoût de copie vers l’espace noyau
    • Unix Domain Socket : permet de contourner entièrement la pile réseau, mais nécessite quand même une copie des données entre l’espace utilisateur et l’espace noyau
    • Shared Memory : une mémoire accessible simultanément par plusieurs processus. Chromium peut y écrire directement, et l’encodeur peut lire immédiatement, sans copie intermédiaire

Implémentation d’un transport basé sur la mémoire partagée

  • les données ont été implémentées sous forme de ring buffer afin de permettre des lectures et écritures continues dans la mémoire partagée
  • exigences : lock-free, multi-producteur / mono-consommateur, taille de frame variable, lecture zero-copy, compatibilité sandbox, signalisation à faible latence
  • après évaluation de plusieurs implémentations existantes de ring buffer, aucune ne satisfaisait l’ensemble des exigences, ils ont donc décidé de l’implémenter eux-mêmes
  • pour prendre en charge la lecture zero-copy, les pointeurs ont été séparés en trois : write, peek et read
  • pour garantir la sûreté entre threads, des opérations atomiques ont été utilisées, ainsi que des named semaphores pour signaler l’arrivée de nouvelles données ou la libération d’espace
  • grâce à l’implémentation de ce ring buffer en mémoire partagée et à d’autres optimisations, ils ont pu réduire jusqu’à 50 % l’utilisation CPU des bots. Au final, cela a permis d’économiser plus d’un million de dollars par an sur les coûts AWS.

3 commentaires

 
GN⁺ 2024-11-08
Avis Hacker News
  • C’est l’histoire typique d’une startup qui choisit un raccourci « suffisamment bon » puis optimise plus tard.

    • Dans une entreprise, il y avait un cluster de VM avec une forte utilisation CPU, et ils ont utilisé un profiler pour l’optimiser.
    • Ils ont réduit l’utilisation CPU en supprimant les anciennes données et en ajoutant des filtres aux requêtes.
  • Certains trouvent surprenante la bande passante très élevée des données vidéo brutes.

    • Ils critiquent les choix de conception de WebSockets, sans avoir anticipé les problèmes d’utilisation CPU.
  • Certains estiment que le problème ne vient pas d’AWS, mais du gaspillage de cycles CPU.

    • WebSockets serait surtout lié au transfert de données ou aux coûts d’API Gateway.
  • Certains soulignent que le MTU et le MSS des réseaux TCP/IP sont petits par rapport à la taille des frames vidéo.

    • Ils pointent un manque de connaissances techniques et affirment qu’il faudrait recruter des développeurs.
  • Certains disent qu’avec Mojo de Chromium, il n’y a pas besoin de se soucier du code spécifique à chaque plateforme.

    • Ils jugent aussi acceptable une implémentation personnalisée de ring buffer.
  • Certains estiment que le problème n’est pas le réseau, mais une mauvaise compréhension des codecs vidéo.

    • Ils disent ne pas comprendre pourquoi un protocole de streaming vidéo comme RDP n’a pas été utilisé.
  • Certains saluent la transparence et disent vouloir aussi de la transparence sur le prix du produit.

  • Certains expliquent que le masking du protocole WebSocket est une tentative de résoudre les problèmes liés aux intermédiaires.

    • Ils ajoutent qu’il vaut la peine de lire la RFC correspondante.
  • Certains trouvent étrange d’envoyer des données vidéo sans compression.

    • Ils disent ne pas comprendre pourquoi un flux compressé n’a pas été utilisé.
  • Certains se disent surpris par l’approche initiale consistant à envoyer de la vidéo brute via WebSocket.

    • Ils estiment que cette inefficacité n’a pourtant pas freiné le développement du produit.
    • Ils disent ne pas comprendre une approche qui ne tient pas compte du volume de données.
 
ahwjdekf 2024-11-09
  • Je pense qu’aucune considération de performance n’a été prise en compte lors du développement du produit.
  • Au final, ce problème se résume à la question de savoir comment faire de l’IPC pour de gros volumes de données.
  • La différence, c’est qu’il ne s’agit pas d’un IPC classique, mais d’un IPC avec le navigateur Chrome, et
  • le fonctionnement interne de Chrome n’est sans doute pas si simple, mais comme c’est ouvert, il est possible de le modifier.
  • Au final, c’est donc une question de choix d’IPC.

Dès le départ, le développement a été mal fait…

 
ahwjdekf 2024-11-09

« Leur approche initiale consistant à transmettre de la vidéo brute via WebSocket est sidérante. » Je partage cet avis.