Question

Cela fait partie de la production cachegrind. Cette partie du code a été exécuté pour 1224 fois. elmg1 est un tableau de unsigned long de taille 16 x 20. Ma machine L1 taille du cache est 32KB, 64B taille de ligne de mémoire cache et 8 voies ensemble associatif.

  1. for (i = 0; i <20; i ++) 78336 2448 50184 2 0 0 1.224 0 0
  2. {
  3. telm01 = elmg1 [i]; 146880 0 0 73440 0 0 24480 0 0
  4. telm31 = (telm01 << 3) ^ val1; 97920 0 0 0 0 48960 24480 0 0
  5. telm21 = (telm01 << 2) ^ (val1 >> 1); 146880 1224 48960 1 0 0 0 0 24480
  6. telm11 = (telm01 << 1) ^ (val1 >> 2); 146880 0 0 48960 0 0 24480 0 0
  7. }

A. La raison pour laquelle je l'ai mis ici, est que, dans la 3ème ligne à l'intérieur de la boucle, je vois un certain nombre de I1 (misses une L2) aussi bien manquer. Il est un peu confus et je ne pouvais pas deviner la raison pour laquelle?

B. Je suis en train d'optimiser (temps) une partie de code. Ce qui précède est juste un petit extrait. Je pense que dans mon accès à la mémoire du programme a me coûte beaucoup. Comme dans l'exemple ci-dessus elmg1 est une matrice de 16 x 20 taille de longs non signés. Lorsque je tente de l'utiliser dans le code, il y a toujours des ratés, et dans mon programme ces variables se produisent beaucoup. Toutes les suggestions?

C. Je dois allouer et (initialiser parfois) ces positions longues non signés. Pouvez-vous suggérer que dois-je préférer, calloc ou déclaration de tableau, puis l'initialisation explicite. Soit dit en passant qu'il y aura une différence dans les poignées de cache de façon elles?

Merci.

Était-ce utile?

La solution

Avez-vous essayé de dérouler la boucle?

  1. Je vous préoccupez pas de L1 misses en ce moment. Aussi une L2 manquez de 1224 fois est ok, le cpu doit charger les valeurs dans le cache à un moment donné.
  2. Quel est le pourcentage de L2 manque coûte ce code par rapport au reste du programme?
  3. Utilisez calloc (), si la taille du tableau est toujours la même et que vous utilisez des constantes pour la taille, le compilateur peut optimiser le zero'ing du tableau. Aussi la seule chose qui aurait un effet les lignes de cache usages est l'alignement, pas comment il a été initizliated.

modifier. Le nombre où difficile à lire de cette façon et les lire mal la première fois

permet de vous assurer que je suis en train de lire les bons chiffres pour la ligne 5:

Ir    146,880
I1mr  1,224
ILmr  1
Dr    48,960
D1mr  0
DLmr  0
Dw    24,480
D1mw  0
DLmw  0

Le cache L1 est divisée en deux caches 32Kbyte une pour le code I1 et l'une des données D1. IL & DL sont le cache L2 ou L3 qui est partagée par des données et des instructions.

Le grand nombre de I1mr est manque d'instruction ne manque de données, cela signifie que le code de boucle est éjectée à partir de la mémoire cache d'instructions I1.

I1 manque à la ligne 1 et 5 au total 3672 qui est 3 fois 1224, de sorte que chaque fois que la boucle est exécutée, vous obtenez 3 I1 manque de cache avec des lignes de cache 64 octets cela signifie que vous taille du code de la boucle est entre 128-192 octets pour couvrir 3 lignes de cache. Donc, ces I1 manque à la ligne 5 est parce que c'est où le code de la boucle traverse la dernière ligne de cache.

Je recommanderais d'utiliser KCachegrind pour visualiser les résultats de cachegrind

Edit:. En savoir plus sur les lignes de cache

Ce code boucle ne ressemble pas à elle est appel 1224 fois par lui-même, de sorte que cela signifie qu'il ya plus de code qui pousse ce code du cache I1.

Votre cache 32Kbyte I1 est divisé en 512 lignes de cache (64bytes chacun). La partie « associative set 8 voies » signifie que chaque adresse de mémoire est mis en correspondance à seulement 8 de ces 512 lignes de cache. Si tout le programme que vous êtes le profil a été un bloc continu de 32KOctets de mémoire, il serait alors tout ajustement dans le cache de I1 et ne serait éjecté. C'est mostlikely pas le cas et il y aura plus de 8 blocs de 64 octets de code pour les mêmes contentant 8 lignes de cache. Disons que votre programme a tout 1Mo de code (ce qui inclut les bibliothèques), chaque groupe de 8 lignes de cache aura environ des morceaux de code 32 (1 Mo / 32Kbyte) pour les mêmes contentant 8 lignes de cache.

Lire cet article lwn.net pour tous les détails sordides sur les caches CPU

Le compilateur ne peut pas toujours détecter les fonctions du programme seront les points chauds (appelé beaucoup de fois) et qui sera codespots (à savoir le code de gestionnaire d'erreurs, qui fonctionne presque jamais). GCC a fonction des attributs chaud / froid qui vous permettra aux fonctions de marque en tant que froid / chaud, ce qui permettra au compilateur de regrouper les fonctions à chaud ensemble dans un bloc de mémoire pour obtenir une meilleure utilisation du cache (code de froid ne sera pas pousser HotCode sur les caches).

Enfin bref ces I1 misses sont vraiment pas la peine le temps de se inquiéter.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top