- Dans le nouveau BIOS de l’ASRock B650 PG Lightning, le loop buffer de Zen 4 n’apparaît plus comme une source de micro-ops, et il est de nouveau actif lorsque l’on revient à l’ancien BIOS
- Cette structure semble destinée à réduire la consommation en rejouant de petites boucles dans le front-end ; sa capacité est estimée à 144 entrées en mono-thread, et à 72 entrées par thread avec deux threads SMT
- Dans SPEC CPU2017, l’écart de score global entre loop buffer activé et désactivé est inférieur à 1 %, ce qui laisse penser que l’impact sur les performances générales est très faible
- Quand le loop buffer est désactivé, Zen 4 fournit davantage de micro-ops depuis l’op cache ; la bande passante de l’op cache étant largement suffisante par rapport au débit du back-end, cela a peu de chances de créer un goulot d’étranglement côté front-end
- La raison de la désactivation et son impact réel sur la consommation restent incertains, mais comme il s’agit d’une fonction limitée qu’AMD n’a presque pas documentée ni mise en avant, la plupart des utilisateurs et développeurs auront du mal à percevoir le changement
Rôle et limites du loop buffer de Zen 4
- Le loop buffer est une structure du front-end CPU qui conserve un petit nombre d’instructions déjà récupérées, afin de pouvoir désactiver certaines étapes du front-end lors de l’exécution répétée de petites boucles
- Il peut contribuer à réduire la consommation
- Il peut aussi améliorer les performances en contournant certaines limites du front-end en amont
- C’est une technique utilisée depuis longtemps dans les cœurs Intel, Arm et AMD
- Zen 4 semble être le seul cas parmi les cœurs AMD hautes performances à disposer d’un loop buffer
- Le Processor Programming Reference de Zen 4 mentionne le loop buffer, aux côtés de l’op cache et des décodeurs, comme source de dispatch de micro-ops
- D’après des expériences avec les compteurs de performance, sa capacité est estimée comme suit
- 144 entrées en exécution mono-thread
- Partitionnement statique à 72 entrées par thread lorsque deux threads SMT sont actifs
- Si une boucle contient CALL/RET, le loop buffer de Zen 4 ne parvient pas à capturer cette boucle
- Le guide d’optimisation Zen 4 d’AMD ne traite pas du loop buffer et se contente de conseiller de maintenir les régions de code chaudes dans la capacité de l’op cache
Le loop buffer disparu après une mise à jour du BIOS
- Après la mise à jour d’une ASRock B650 PG Lightning vers le BIOS 3.10, le monitoring matériel des performances indique que le loop buffer ne dispatche plus de micro-ops
- En revenant au BIOS 1.21, le loop buffer est de nouveau activé
- La désactivation semble être intervenue entre AGESA 1.0.0.6 du BIOS 1.21 et AGESA 1.2.0.2a du BIOS 3.10
- AMD a appliqué ce changement sans annonce ni communication particulière
- D’après des discussions complémentaires avec des employés d’AMD à Hot Chips 2024, le loop buffer était principalement une fonction destinée à l’optimisation énergétique
Un faible écart de performances dans SPEC CPU2017
- Le score global des suites entiers et flottants de SPEC CPU2017 ne diffère que de moins de 1 % selon que le loop buffer est activé ou désactivé
- Le gain de performances en SMT n’est pas non plus affecté par la désactivation du loop buffer
- Si l’impact sur les performances est faible, c’est parce que l’op cache de Zen 4 fournit déjà davantage de bande passante que ce que l’étape de rename/allocate du back-end peut consommer
- Même lorsque le loop buffer est activé, les compteurs de performance indiquent que seule une petite fraction des micro-ops en provient
- Aucun gros recul n’est observé dans les benchmarks individuels
- 523.xalanbmk faisait traiter au loop buffer une minorité significative de l’instruction stream, mais le score reste dans la marge d’erreur : 9,48 avec le nouveau BIOS contre 9,44 avec l’ancien
- 544.nab recevait près d’un quart de ses micro-ops du loop buffer, mais son score progresse à 11,7 avec le nouveau BIOS où le loop buffer est désactivé, contre 11,5 auparavant, soit +1,7 %
- Cette hausse peut relever de la variance d’une exécution à l’autre
- Dans les compteurs de performance du nouveau BIOS, l’op cache reprend la part du loop buffer et traite une plus grande proportion de l’instruction stream
- Dans 507.cactuBSSN, la couverture de l’op cache diminue en partie et les décodeurs semblent fournir environ un quart de l’ensemble des micro-ops
- Les compteurs de performance sont des outils qui montrent des tendances générales plutôt que des mesures exactes à 100 %
- Le dispatch front-end est un événement spéculatif et peut donc être influencé par des instructions récupérées à tort après une branche mal prédite
Économies d’énergie possibles et activité du front-end
- Le principal objectif du loop buffer n’est pas d’améliorer les performances, mais d’éteindre de manière opportuniste une grande partie du front-end, y compris l’op cache
- Les fonctions de monitoring des performances de Zen 4 disposent d’un count mask permettant de compter les cycles pendant lesquels le nombre d’événements dépasse un seuil
- En fixant le seuil à 1, on peut estimer le nombre de cycles pendant lesquels chaque source de micro-ops fournit effectivement des micro-ops
- Cela permet d’évaluer à quelle fréquence le front-end pourrait être désactivé lorsque le loop buffer est actif
- Dans SPEC CPU2017, la fréquence d’activation de chaque source correspond globalement bien à la proportion de micro-ops qu’elle transmet
- Dans certaines charges de travail, les cycles où le front-end ne fournit rien sont également nombreux
- 502.gcc et 520.omnetpp sont fortement contraints par la latence mémoire du back-end
- Si le moteur d’exécution out-of-order ne parvient pas à maintenir suffisamment d’instructions en vol pour masquer la latence, le front-end ne peut plus envoyer davantage vers le back-end et se retrouve à l’arrêt
- Dans la suite flottante, 544.nab et 508.namd utilisent le loop buffer pendant une part assez importante des cycles cœur
- 508.namd est une charge de travail à IPC élevé, avec 3,64 IPC en moyenne, et demande donc un débit front-end important
- Elle est favorable au loop buffer, ce qui offre des occasions d’éteindre l’op cache pour économiser de l’énergie
- Quand le loop buffer est désactivé, l’op cache alimente le cœur pendant davantage de cycles
- Dans 523.xalanbmk, sans loop buffer, l’op cache doit être actif pendant 12 % de cycles cœur supplémentaires
- 548.exchange2 est une charge à IPC élevé, avec 4,31 IPC en moyenne, mais utilise très peu le loop buffer même lorsqu’il est activé, et l’op cache est actif pendant plus de 85 % des cycles cœur
- Dans 508.namd, la part d’activation de l’op cache passe de 56,67 % lorsque le loop buffer est activé à 75,1 % lorsqu’il est désactivé
- Un loop buffer de 144 entrées est trop petit pour contenir une grande partie de l’instruction stream
- Il n’a de chances d’avoir un effet net que si un programme passe une part importante de son temps dans de petites boucles et n’est pas limité par le débit ou la latence du back-end
Observations dans Cyberpunk 2077
- L’impact de la désactivation du loop buffer sur les performances en jeu a été vérifié avec le benchmark intégré de Cyberpunk 2077
- Pour améliorer la cohérence, Core Performance Boost a été désactivé sur un Ryzen 9 7950X3D et tous les cœurs ont été limités à 4,2 GHz
- Le bit 25 du registre Hardware Configuration MSR 0xC0010015 a été défini
- La RX 6900 XT a été limitée à 2 GHz
- Le benchmark a été exécuté en 1080p, preset medium, sans upscaling
- Lorsque le jeu est épinglé au die VCache, la désactivation du loop buffer n’a presque aucun impact sur les performances
- Lorsqu’il est épinglé au die non-VCache, une perte de performances de 5 % est observée avec la désactivation du loop buffer, mais la cause n’a pas été identifiée
- Le benchmark a été relancé environ six fois
- Dans Cyberpunk 2077, le loop buffer prend en charge en moyenne environ 22 % de l’instruction stream, ce qui le rend plus favorable au loop buffer que prévu
- Après désactivation du loop buffer, la part des micro-ops fournies par l’op cache passe de 62 % à 82 %
- Ce jeu n’est pas une charge de travail à IPC élevé : 0,89 IPC en moyenne avec le loop buffer désactivé, contre 1,02 IPC lorsqu’il est activé
- La bande passante du front-end n’est pas un facteur majeur
- Il est possible qu’il soit limité par le back-end ou par le délai du prédicteur de branchement
- Lors de l’exécution sur le die VCache, les compteurs de performance affichent 1,25 IPC en moyenne avec le loop buffer activé, contre 1,07 IPC lorsqu’il est désactivé
- Une légère baisse de performances est également observée avec le nouveau BIOS
- À environ 155 FPS, la charge s’est peut-être rapprochée d’un goulot d’étranglement côté GPU
Incertitude des résultats des compteurs d’énergie cœur
- Les compteurs d’énergie cœur de Zen 4 ont également été examinés afin de vérifier si l’exécution depuis le loop buffer améliore l’efficacité énergétique
- Le benchmark de bande passante d’instructions a été modifié pour ne pas utiliser CALL/RET dans la section testée
- En effet, Zen 4 n’utilise pas le loop buffer en présence de CALL/RET
- Le test est épinglé à un cœur, et la puissance moyenne est calculée en lisant le Core Energy Status MSR avant et après le saut vers le tableau de test
- Core Performance Boost a été désactivé, car les lectures de puissance fluctuaient fortement
- Avec l’ancien BIOS, le Core Energy Status MSR indiquait 6 W en moyenne lors de la récupération de NOP depuis l’op cache, et une consommation bien plus faible depuis le loop buffer
- Même en portant la taille du tableau de test à 128 KB, soit de quoi tenir dans le L2, afin d’abaisser la couverture de l’op cache sous 1 %, la puissance cœur moyenne indiquée était de 1,5 W
- Ce résultat ne correspond pas à une situation où l’utilisation des décodeurs et du chemin de fetch L2 devrait augmenter
- Avec le nouveau BIOS, le test depuis l’op cache indique 1,68 W en moyenne, et le test majoritairement alimenté par les décodeurs depuis le L2 affiche une puissance presque identique
- Les fonctions de monitoring énergétique d’AMD peuvent relever d’une modélisation de puissance plutôt que d’une mesure réelle
- La méthode de modélisation a peut-être changé entre les versions de BIOS, ou le modèle de puissance peut être inexact
- Faute de matériel permettant une mesure directe, par exemple sur les connecteurs EPS 12 V, aucune vérification supplémentaire n’a été effectuée
Raisons de la désactivation et point de vue développeur
- La raison pour laquelle AMD a désactivé le loop buffer de Zen 4 n’est pas connue
- Des fonctions CPU sont parfois désactivées à cause de bugs matériels
- Le LSD, loop buffer d’Intel Skylake, a été désactivé en raison d’un bug lié aux accès à des registres partiels dans de courtes boucles lorsque les deux threads SMT sont actifs
- Zen 4 est la première tentative d’AMD d’intégrer un loop buffer à un CPU hautes performances, et valider une première implémentation est difficile
- AMD a peut-être découvert en interne un bug non visible publiquement et désactivé le loop buffer à titre préventif
- L’impact sur les performances devrait être nul ou très faible, car la bande passante de l’op cache est suffisante
- L’impact sur la consommation est inconnu, mais il pourrait être faible et difficile à mesurer
- AMD n’a presque pas documenté ni promu le loop buffer, hormis une ligne dans le Processor Programming Reference
- Cela contraste avec Intel, qui documente souvent son loop buffer et recommande dans ses guides d’optimisation que les développeurs l’exploitent
- Le loop buffer de Zen 4 est une fonction limitée, moins utile que l’op cache en raison de sa faible capacité et de la contrainte CALL/RET
- Si l’on optimise consciemment pour le loop buffer de Zen 4 avec un ancien BIOS, les conditions suivantes peuvent être prises en compte
- Maintenir les boucles sous 144 micro-ops
- Si deux threads partagent un cœur physique, tenir compte d’une capacité environ divisée par deux
- Pour les fonctions appelées dans de petites boucles, envisager l’inlining afin d’éviter CALL/RET
- Même avec ces optimisations, il est très probable que le gain soit inexistant dans la plupart des cas
1 commentaires
Avis sur Hacker News
On peut supposer que cette fonctionnalité a été désactivée pour tenter de prévenir une vulnérabilité matérielle non divulguée
Il n’est pas déraisonnable d’imaginer qu’AMD ait découvert en interne un bug que personne n’avait encore rencontré, et ait désactivé le tampon de boucle par excès de prudence. À ce stade du cycle de vie du cœur, on voit mal quelle autre raison AMD aurait de toucher au frontend de Zen 4
Personnellement, ça sent la mesure d’atténuation par microcode, mais il faut évidemment attendre un CVE
Si la vulnérabilité n’est pas divulguée, les parties touchées n’ont aucun moyen de commencer à réagir, sauf par pure paranoïa. La divulgation d’une vulnérabilité est aussi une façon de transférer la responsabilité vers l’utilisateur final : si vous n’avez pas fait la mise à jour, ne venez pas vous plaindre. Il est rare qu’une divulgation débouche sur une responsabilité produit, et je ne me souviens pas que cette question se soit posée avec Meltdown ou Spectre. Donc je n’affirmerais pas qu’AMD cache délibérément quelque chose
L’article semble suggérer que le tampon de boucle n’apporte ni gain de performances ni gain énergétique.
Dans ce cas, ce pourrait être le grand classique de « une équipe d’ingénieurs a passé des mois à créer une nouvelle fonctionnalité brillante qui n’apporte finalement rien, mais quelqu’un l’a quand même lancée pour sauver la face ». J’ai déjà vu des équipes logiciel vouloir réécrire une base de code pour supprimer de la lourdeur legacy et améliorer les performances, pour finir avec plus de lignes de code et de moins bonnes performances. Dans les deux cas, il n’aurait pas fallu sortir ça
Il est difficile de croire que l’équipe d’ingénierie d’AMD soit assez peu rigoureuse pour laisser une fonctionnalité matérielle sans aucune valeur consommer de la surface et de l’énergie ; ici, j’aurais plutôt tendance à penser que Chips 'n Cheese n’a pas réussi à en mesurer l’impact
C’est très frustrant, mais personne ne veut prendre le temps de faire l’étude préalable. Pousser un nouveau projet satisfait davantage la hiérarchie et attire moins de questions
Le paragraphe le plus intéressant de l’article est celui-ci : la meilleure façon de voir le tampon de boucle de Zen 4, c’est comme le signe qu’AMD dispose d’une marge de capacité permettant à ses ingénieurs d’essayer des choses.
Cette fois, cela n’a peut-être pas donné de résultat, mais laisser des ingénieurs expérimenter sur des fonctionnalités à faible risque et faible impact est une bonne façon de bâtir de la confiance. J’espère que l’on verra davantage de cette confiance à l’avenir
Le passage disant qu’« étrangement, lorsqu’on force l’exécution sur le die non-VCache, désactiver le tampon de boucle fait chuter les performances en jeu de 5 %. Je ne sais pas pourquoi » me fait penser qu’avec des mesures d’énergie plus fines, on pourrait déterminer si c’est lié au budget thermique/énergétique.
Cette fonctionnalité semble aussi avoir été pensée pour économiser de l’énergie
Sur ma puce non-X3D, la plupart des cœurs du CCD0 montent à 5,6–5,75 GHz, tandis que ceux du CCD1 plafonnent à 5,4–5,5 GHz. Les puces V-Cache Zen 4 subissent une forte pénalité de fréquence, mais le cache compense largement. Il faudrait savoir s’ils ont testé, sur le CCD1 de la même puce, la fonctionnalité activée puis désactivée, et s’ils ont essayé d’isoler d’autres changements comme des correctifs de sécurité ; l’article reconnaît lui-même que « non ». Pour le faire correctement, il faudrait trouver un moyen de désactiver uniquement cette fonctionnalité dans un BIOS où elle est activée, puis tester les deux configurations sur la même puce ; même là, d’autres conditions de branchement pourraient rendre les résultats imprécis. Un profil de performances complet améliorerait la précision, mais seuls des ingénieurs AMD peuvent probablement le faire
Cela semble avoir été trop petit pour faire une vraie différence, et utile seulement dans des situations très spécifiques. En le rendant plus important, le coût d’implémentation aurait sans doute été trop élevé par rapport au bénéfice.
Cela dit, il y aura quand même de légères régressions sur certaines charges de travail, mais AMD a aussi apporté de petites améliorations de performances après la sortie. Sur Zen 4, ils auraient simplement dû en faire une option BIOS. Le fait qu’ils ne semblent pas l’avoir fait suggère la possibilité d’un bug ou d’un problème de sécurité
À titre anecdotique, l’une des rares différences entre le 68000 de 1979 et le 68010 de 1982 était le « loop mode », c’est-à-dire l’ajout d’un tampon de boucle de 6 octets.
Elle consistait à faire tourner deux CPU avec un cycle de décalage et à injecter une interruption récupérable dans le second CPU. Mais si l’on voulait un CPU avec MMU, un jeu d’instructions 32 bits et un bus d’adresses 24 bits, cela semblait tout de même moins cher que les alternatives de l’époque. Quelle période rude cela devait être.
Un mot de 18 bits contient 4 instructions, et l’un des opcodes décrémente le compteur de boucle puis revient au début du mot. Dans ce cas, l’exécution peut être nettement plus rapide.
L’une d’elles devait être l’instruction de boucle (DBcc), donc le corps de la boucle devait être une seule instruction. En pratique, à peu près la seule chose qui pouvait réellement accélérer était un memcpy non optimisé.
Il est intéressant de voir que, sur le Cortex-A15, c’est une fonction de conception clé. Je me demande s’il existe des chiffres sur son efficacité dans d’autres puces.
Dans des appareils à durée de vie de conception plus longue, comme les consoles, cela pourrait au moins servir de cible d’optimisation.
Après tout, l’idée du RISC est de rendre la récupération et le décodage des instructions beaucoup plus faciles, voire presque triviaux.
J’ai un 7950X3D, après être passé d’un Skylake 6700K. Apparemment, je suis inconsciemment attiré par les puces dont le tampon de boucle matériel est désactivé par logiciel.
Article intéressant, mais je ne sais pas combien de place le tampon de boucle occupe sur le die.
Je me demande si, en le supprimant dans de futures puces, cet espace pourrait être utilisé pour quelque chose de plus utile, comme un cache L2 plus grand.
En théorie, un tampon de boucle peut économiser de l’énergie ou améliorer les performances dans des boucles serrées. En pratique, il semble ne faire ni l’un ni l’autre, et AMD l’a complètement supprimé dans Zen 5.
Si c’est exact, c’est plausible, et le coût en surface se limite à peu près à de la logique de contrôle supplémentaire. La partie la plus coûteuse est probablement la détection même des boucles, mais cela doit rester assez petit par rapport à la taille de la file.
L’analyse de la section « énergie » semble ne pas être divisée par le nombre d’instructions exécutées par seconde.
Pour voir l’intérêt de ce tampon de boucle, il faut presque certainement regarder l’énergie par instruction, et non l’énergie par seconde, c’est-à-dire la puissance (en watts).
Même l’ordre et le contenu de la RAM peuvent tout changer. On peut exécuter des centaines de fois avec et sans l’option pour isoler le phénomène dans une certaine mesure, mais cela prend énormément de temps et ne sera quand même pas exact à 100 %. Le simple fait de désactiver une fonctionnalité peut faire emprunter au code une autre branche, ce qui change toute la disposition. Je ne connais pas ce problème précisément, mais j’ai déjà vu des cas où la désactivation d’une fonctionnalité déplaçait la charge des unités entières vers le FPU ou le GPU, ou supprimait 5 instructions tout en en ajoutant 2.