37 votes

Écriture d'un programme pour obtenir la taille de la ligne de cache (L1)

Comme un devoir scolaire, j'ai besoin de trouver un moyen d'obtenir la L1 cache de données de la ligne de taille, sans la lecture des fichiers de configuration ou de l'utilisation d'appels d'api. Censé utiliser les accès à la mémoire en lecture/écriture des horaires à analyser et obtenir cette info. Alors, comment pourrais-je le faire?

Incomplet, essayez pour une autre partie de la mission pour trouver les niveaux et taille de la mémoire cache, j'ai:

for (i = 0; i < steps; i++) {
    arr[(i * 4) & lengthMod]++;
}

Je pensais peut-être que j'ai juste besoin de varier la ligne 2, (i * 4) de la partie? Donc, une fois que je dépasse la taille de ligne de cache, j'ai peut-être besoin de les remplacer, ce qui prend parfois? Mais est-ce si simple? Le bloc peut-être déjà en mémoire quelque part? Ou perpahs je peut toujours compter sur le fait que si j'ai un assez grand steps, il faudra encore travailler très précisément?

Mise à JOUR

Heres une tentative sur GitHub ... partie principale ci-dessous

// repeatedly access/modify data, varying the STRIDE
for (int s = 4; s <= MAX_STRIDE/sizeof(int); s*=2) {
    start = wall_clock_time();
    for (unsigned int k = 0; k < REPS; k++) {
        data[(k * s) & lengthMod]++;
    }
    end = wall_clock_time();
    timeTaken = ((float)(end - start))/1000000000;
    printf("%d, %1.2f \n", s * sizeof(int), timeTaken);
}

Le problème est là ne semblent être beaucoup de différences entre le calendrier. FYI. depuis sa pour le cache L1. J'ai SIZE = 32 K (la taille de la table)

29voto

Alex D Points 14591

Allouer un GROS char tableau (assurez-vous qu'il est trop grand pour tenir en L1 ou L2 cache). Le remplir avec des données aléatoires.

Commencer à marcher sur le tableau dans les étapes de l' n octets. Faire quelque chose avec l'extrait d'octets, comme en faisant la somme.

Indice de référence et de calculer le nombre d'octets/seconde, vous pouvez traiter avec les différentes valeurs de n, à partir de 1 et de comptage jusqu'à 1000. Assurez-vous que votre référence imprime le montant calculé, de sorte que le compilateur ne peut pas optimiser les indices de référence de code.

Lors de l' n == votre taille de ligne de cache, chaque accès exigeront de la lecture d'une nouvelle ligne dans le cache L1. Donc, les résultats de la référence devrait se ralentir très fortement à ce point.

Si le tableau est assez grand, au moment où vous atteignez la fin, les données sur le début du tableau sera déjà de cache de nouveau, qui est ce que vous voulez. Donc, après vous incrément n et de commencer à nouveau, les résultats ne seront pas touchés par avoir besoin de données déjà dans le cache.

5voto

auselen Points 13961

Jetez un oeil à Calibrateur, tout le travail est protégé, mais le code source est librement disponible. À partir de son document idée pour calculer les tailles de ligne de cache semble beaucoup plus instruits que ce qui est déjà dit ici.

L'idée sous-jacente à notre étalon outil est d'avoir un micro de référence dont la performance dépend uniquement sur la fréquence des échecs de cache qui se produisent. Notre étalon est un simple programme en C, et surtout une petite boucle qui exécute un million de lectures de mémoire. Par la modification de la foulée (c'est à dire, le décalage entre les deux les accès à la mémoire) et de la taille de la zone mémoire, nous force allant de cache miss taux.

En principe, la survenance de défauts de cache est déterminée par la taille de la matrice. Tableau des tailles qui correspondent à le cache L1 ne génère pas de défauts de cache, une fois les données chargées dans le cache. De la même façon, les tableaux qui dépassent la taille du cache L1, mais encore entrer dans L2, seront la cause de L1 manque, mais pas de L2 manque. Enfin, tableaux supérieure à celle de la L2 provoquer à la fois en L1 et en L2 manque.

La fréquence des échecs de cache dépend de l'accès de la foulée et la taille de ligne de cache. Avec les progrès égale ou plus grande que la taille de ligne de cache, un cache miss se produit à chaque itération. Avec les progrès plus petite que la taille de ligne de cache, un cache miss ne se produit que tous les n itérations (en moyenne), où n est le ratio cache ligne taille/la foulée.

Ainsi, nous pouvons calculer le temps de latence pour un cache miss en comparant les temps d'exécution sans manque le temps d'exécution avec exactement une miss par itération. Cette approche fonctionne seulement si les accès à la mémoire sont exécutées purement séquentielle, c'est à dire, nous devons nous assurer que ni deux, ou plus de charge des instructions ni d'accès à la mémoire et pur de l'UC de travail peuvent se chevaucher. Nous utilisons un simple pointeur de chasser mécanisme à cet effet: la zone de mémoire nous avons accès est initialisé à ce que chaque charge renvoie la adresse pour la suite de la charge lors de la prochaine itération. Ainsi, le super-scalaire Processeurs ne peuvent pas bénéficier de leur capacité à masquer la latence d'accès à la mémoire par la spéculation sur l'exécution.

Pour mesurer les caractéristiques de cache, nous courons à notre expérience plusieurs fois, en variant la foulée et la taille de la matrice. Nous nous assurons que la foulée varie au moins entre 4 octets, et deux fois au maximum attend taille de ligne de cache, et que la taille de la matrice varie de la moitié de la minimale attendue taille de la mémoire cache au moins dix fois le maximum prévu la taille du cache.

J'ai eu à commenter #include "math.h" pour l'obtenir compilé, après qu'il a trouvé mon ordinateur portable en cache les valeurs correctement. Je n'avais pas afficher les fichiers postscript généré.

2voto

Alexey Matveev Points 89

Je pense que vous devriez écrire un programme, qui parcourra le tableau dans un ordre aléatoire à la place, car le processus moderne fait de la prélecture matérielle. Par exemple, créez un tableau d'int, dont les valeurs seront le numéro de la cellule suivante. J'ai fait un programme similaire il y a 1 an http://pastebin.com/9mFScs9Z Désolé pour mon anglais, je ne suis pas natif.

1voto

vitaly.v.ch Points 1143

Voyez comment memtest86 est implémenté. Ils mesurent et analysent le taux de transfert de données d'une manière ou d'une autre. Les points de changement de débit correspondent à la taille de L1, L2 et à la taille de cache L3 possible.

1voto

JimR Points 4816

Si vous êtes coincé dans la boue et ne pouvez pas sortir, regardez ici .

Il existe des manuels et du code qui expliquent comment faire ce que vous demandez. Le code est également de très bonne qualité. Regardez "Bibliothèque de sous-programmes".

Le code et les manuels sont basés sur des processeurs X86.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X