Vous êtes certainement obtenir ce que j'appelle un cache de résonance. Ceci est similaire à l'aliasing, mais pas exactement le même. Laissez-moi vous expliquer.
Les Caches sont de matériel de structures de données qui extrait une partie de l'adresse et de l'utiliser comme un index dans une table, pas contrairement à un tableau dans le logiciel. (En fait, nous les appelons des tableaux dans le matériel.) Le tableau de cache contient des lignes de cache de données, et des étiquettes - parfois, une telle entrée par l'index dans le tableau (direct mapped), parfois plusieurs de ces (N-way set associativité). Une deuxième partie de l'adresse est extrait et par rapport à la balise stockés dans le tableau. Ensemble, l'index et le tag identifier de manière unique une ligne de cache de la mémoire d'adresse. Enfin, le reste des bits de l'adresse permet d'identifier les octets de la ligne de cache sont abordées, ainsi que la taille de l'accès.
Habituellement, l'index et le tag sont simples bitfields. Si une adresse de mémoire ressemble
...Tag... | ...Index... | Offset_within_Cache_Line
(Parfois, l'index et le tag sont les tables de hachage, par exemple, quelques XORs d'autres bits dans le milieu de gamme, les bits qui sont à l'index. Beaucoup plus rarement, parfois, les index, et plus rarement tag, sont des choses comme la prise en cache de l'adresse de ligne modulo un nombre premier. Ces plus compliqué calculs d'indice sont des tentatives visant à lutter contre le problème de la résonance, qui je l'explique ici. Tous souffrent d'une certaine forme de résonance, mais le plus simple champ de bits systèmes d'extraction souffrent de résonance sur la commune de modèles d'accès, comme vous l'avez trouvé.)
Ainsi, les valeurs typiques... il y a beaucoup de modèles différents de "Opteron Dual Core", et je ne vois rien ici qui spécifie que vous avez. Choisir un au hasard, le plus récent manuel je vois sur le site web d'AMD, le Bios et le Noyau Guide du Développeur (BKDG) pour AMD de la Famille 15h Modèles 00h-0Fh, le 12 Mars 2012.
(Famille 15h = Bulldozer de la famille, le plus récent haut de gamme de processeur - la BKDG mentionne dual core, mais je ne sais pas le numéro du produit, c'est exactement ce que vous décrivez. Mais, de toute façon, la même idée de la résonance s'applique à tous les processeurs, c'est juste que les paramètres tels que la taille de la mémoire cache et l'associativité peut varier un peu.)
À partir de p.33:
L'AMD Famille 15h processeur contient un 16 kilo-octets, 4-way prédit L1
cache de données avec deux de 128 bits ports. C'est un cache à écriture immédiate que
prend en charge jusqu'à deux 128 Octets charge par cycle. Il est divisé en 16
les banques, chaque 16 octets. [...] Une seule charge peut être effectuée à partir d'un
compte tenu de la banque de la L1 cache en un seul cycle.
Pour résumer:
De 64 octets par ligne de cache => 6 décalage de bits à l'intérieur de ligne de cache
-
16KO/4-way => la résonance est de 4 ko.
I. e. bits de l'adresse 0 à 5 sont la ligne de cache de décalage.
16KO / 64B lignes de cache => 2^14/2^6 = 2^8=128 les lignes de cache dans le cache.
-
4 chemin associatif => 128/4 = 32 index dans le tableau de cache. J' (Intel) appel de ces "ensembles".
c'est à dire que vous pouvez envisager de la cache comme un tableau de 32 entrées ou les séries, chaque entrée contenant 4 lignes de cache annonce de leurs tags. (C'est plus compliqué que cela, mais ce n'est pas grave).
(En passant, les termes "set" et "moyen" ont des définitions différentes.)
-
il y a 5 indice de bits, les bits 6 à 10 dans le plus simple régime.
Cela signifie que toutes les lignes de cache qui ont exactement les mêmes valeurs dans l'indice de bits, les bits 6 à 10, correspond à la même série de la cache.
Maintenant, regardez votre programme.
C[dimension*i+j] += A[dimension*i+k] * B[dimension*k+j];
Boucle k le plus proche du centre de la boucle. Le type de base est double, de 8 octets. Si la dimension=2048, c'est à dire 2K, alors éléments successifs d' B[dimension*k+j]
accessible par la boucle sera de 2048 * 8 = 16 K octets en dehors. Ils seront tous de carte pour le même jeu de la L1 cache - ils ont tous le même indice dans le cache. Ce qui signifie que, au lieu de 128 lignes de cache dans le cache disponible pour l'utilisation, il y aura seulement 4 - la "4 voies associativité" de la cache.
I. e. vous obtiendrez probablement un cache miss tous les 4 itérations autour de cette boucle. Pas bonne.
(En fait, les choses sont un peu plus compliquées. Mais ce qui précède est une première bonne compréhension. Les adresses des entrées de B mentionné ci-dessus est une adresse virtuelle. Il y aurait peut-être légèrement différente de l'adresse physique. En outre, le Bulldozer a une façon prédictive cache, probablement à l'aide des adresses virtuelles bits, afin de ne pas avoir à attendre pour un virtuelle et adresse physique de la traduction. Mais, dans tous les cas: votre code a une "résonance" de 16K. Le cache de données L1 a une résonance de 16K. Pas bon.)]
Si vous modifiez la dimension juste un peu, par exemple à 2 048+1, alors les adresses de la matrice B seront répartis à travers tous les jeux de la mémoire cache. Et vous aurez beaucoup moins de défauts de cache.
Il est assez commun d'optimisation pour étoffer vos tableaux, par exemple pour changer à 2048 2049, pour éviter cette théorie de la relativité restreinte de la résonance. Mais "cache le blocage est encore plus important de l'optimisation. http://suif.stanford.edu/papers/lam-asplos91.pdf
En plus de la ligne de cache de résonance, il y a d'autres choses qui se passent ici. Par exemple, le cache L1 a 16 banques, chacune de 16 octets. Avec la dimension = 2048, successives B accède à l'intérieur de la boucle de la volonté de toujours aller à la même banque. Donc ils ne peuvent pas aller en parallèle - et si l'Un d'accès pour aller à la même banque, vous allez perdre.
Je ne pense pas, en le regardant, que c'est aussi grand que le cache de résonance.
Et, oui, probablement, il peut être aliasing va. E. g. le STLF (Magasin À la Charge de la Redirection de tampons) peut-être que la comparaison à l'aide d'un petit champ de bits, et d'obtenir de mauvais résultats.
(En fait, si vous pensez à ce sujet, la résonance dans le cache, c'est comme l'aliasing, liés à l'utilisation de bitfields. La résonance est causé par de multiples lignes de cache cartographie de la même série, ne diffuse pas arond. Alisaing est causée par le matching basé sur incomplète bits de l'adresse.)
Dans l'ensemble, ma recommandation pour le paramétrage:
Essayez de cache de blocage, sans autre analyse. Je dis cela, car le cache de blocage est facile, et il est très probable que c'est tout ce que vous devez faire.
Après cela, utilisez VTune ou OProf. Ou Cachegrind. Ou ...
Mieux encore, utilisez un bien à l'écoute de la bibliothèque de routine, la matrice se multiplier.