ThreadSpotterThreadSpotter est un outil qui diagnostique les problèmes de performances liés à la localité des données, à l'utilisation du cache et à l'interaction des threads. De manière générale, la bande passante du bus mémoire n'a pas connu les mêmes améliorations que les augmentations de performances des CPU (une observation parfois appelée memory wall (en)), et avec les systèmes multi-cœur, la bande passante disponible est partagée entre tous les cœurs. Cela fait de la préservation de cette bande passante l'une des tâches les plus importantes à accomplir afin d'obtenir des performances optimales. ThreadSpotter détermine les schémas des modèles d'accès mémoire sous-optimaux et leur applique une heuristique afin de les catégoriser, d'en expliquer les causes et de proposer des pistes d'améliorations du code. L'outil dispose de capacités prédictives permettant de modéliser les caractéristiques des performances d'un code en fonction d'une architecture donnée (taille de cache, modèle de processeur...). Cette possibilité d'analyse autorise l'exploration de différents scénarios à partir d'un échantillonnage unique. Localité spatialeLa Localité Spatiale fait référence à la propriété avantageuse d'accéder à des emplacements mémoires proches les uns des autres. Une faible localité spatiale est pénalisante pour différentes raisons :
ThreadSpotter indique lorsqu'au moins l'un des points suivants devient pénalisant en matière de Localité Spatiale :
Localité temporelleLa Localité Temporelle fait référence à la réutilisation des données. Réutiliser des données alors qu'elles sont encore dans le cache diminue la quantité de fetchs nécessaires et réduit généralement la charge du bus mémoire. ThreadSpotter classe ces possibilités d'optimisation en :
Latence mémoireLe temps qu'il faut pour initier un chargement mémoire (memory fetch) est appelé latence mémoire. Pendant ce temps, le CPU est bloqué. La pénalité induite par cette latence est de l'ordre de 100 cycles d'horloge. Les caches ont été conçus pour masquer de tels problèmes, en traitant une quantité limitée de données à partir d'une mémoire de petite taille, mais extrêmement rapide. Cette méthode est efficace si l'ensemble des données peut être contraint à être contenu dans le cache. Il existe une autre technique appelée préchargement mémoire (memory prefetch), où le transfert de données est effectué explicitement ou automatiquement avant que celles-ci ne soient requises. L'objectif est de faire que ces données soient déjà présentes dans le cache avant qu'elles ne soient sollicitées. ThreadSpotter identifie dans ce domaine les problèmes suivants :
De plus, l'outil évalue l'efficacité du mécanisme matériel de préchargement (hardware prefetcher) en modélisant son comportement et en enregistrant les cas de :
Éviter la pollution du cacheSi les données occupent une quantité de mémoire plus grande que le cache disponible et qu'il n'y a pas de manière pratique de réorganiser les schémas d'accès pour améliorer la réutilisation des données, alors il n'y a aucun avantage à stocker en premier lieu ces données dans le cache. Certains processeurs disposent à cet effet d'instructions spéciales permettant de contourner l'utilisation des caches. ThreadSpotter trouve des opportunités de :
Cohérence de cacheLorsqu'il y a plusieurs caches dans un système, la consistance des uns envers les autres doit être assurée. Les activités gérant cette cohérence des données prennent un certain temps pour être menées à bien. De la même manière qu'il est important d'observer les propriétés de localité dans la façon dont vous accédez aux emplacements de la mémoire vive, il est important de prêter attention et de limiter le trafic lié à cette cohérence. Par exemple, dans un scénario producteur / consommateur où deux threads utilisent un morceau de mémoire partagée pour transférer des données entre elles, le propriétaire de cette mémoire va à plusieurs reprises passer de cache producteur à cache consommateur. Si toutes les données dans une ligne de cache ne sont pas entièrement consommées, mais que le producteur visite à nouveau la ligne de cache, alors on est dans le cas d'un modèle de communication pauvre. Il serait plus approprié de remplir la ligne de cache dans son intégralité avant de la remettre au consommateur. Interaction des threadsSi deux threads utilisent chacun leur propre variable, mais si ces variables sont amenées à partager une même ligne de cache, alors son appartenance va tour à tour passer d'un thread à l'autre. Ce problème peut généralement être résolu en forçant les variables à ne pas résider sur la même ligne de cache. ThreadSpotter identifie ce phénomène comme cas de : Effets du partage de cachePour les CPU disposant de plusieurs niveaux de caches, leur topologie est parfois asymétrique dans le sens où le coût de communication entre deux caches de même niveau n'est pas uniforme. Liens externesInformation related to ThreadSpotter |