Toutes les plates-formes sont les bienvenues, veuillez spécifier la plate-forme pour votre réponse.
Une question similaire: Comment obtenir par programme la taille de la page de cache du processeur en C++?
Sous Linux (avec un noyau raisonnablement récent), vous pouvez obtenir ces informations à partir de/sys:
/sys/devices/system/cpu/cpu0/cache/
Ce répertoire a un sous-répertoire pour chaque niveau de cache. Chacun de ces répertoires contient les fichiers suivants:
coherency_line_size
level
number_of_sets
physical_line_partition
shared_cpu_list
shared_cpu_map
size
type
ways_of_associativity
Cela vous donne plus d'informations sur le cache que vous n'auriez jamais espéré connaître, y compris la taille de la cacheline (coherency_line_size
) ainsi que les processeurs qui partagent ce cache. Ceci est très utile si vous effectuez une programmation multithread avec des données partagées (vous obtiendrez de meilleurs résultats si les threads partageant des données partagent également un cache).
Sous Linux, regardez sysconf (3).
sysconf (_SC_LEVEL1_DCACHE_LINESIZE)
Vous pouvez également l'obtenir à partir de la ligne de commande en utilisant getconf:
$ getconf LEVEL1_DCACHE_LINESIZE
64
Je travaillais sur certains éléments de la ligne de cache et j'avais besoin d'écrire une fonction multiplate-forme. Je l'ai engagé dans un dépôt github à l'adresse https://github.com/NickStrupat/CacheLineSize , ou vous pouvez simplement utiliser la source ci-dessous. N'hésitez pas à faire ce que vous voulez avec.
#ifndef GET_CACHE_LINE_SIZE_H_INCLUDED
#define GET_CACHE_LINE_SIZE_H_INCLUDED
// Author: Nick Strupat
// Date: October 29, 2010
// Returns the cache line size (in bytes) of the processor, or 0 on failure
#include <stddef.h>
size_t cache_line_size();
#if defined(__Apple__)
#include <sys/sysctl.h>
size_t cache_line_size() {
size_t line_size = 0;
size_t sizeof_line_size = sizeof(line_size);
sysctlbyname("hw.cachelinesize", &line_size, &sizeof_line_size, 0, 0);
return line_size;
}
#Elif defined(_WIN32)
#include <stdlib.h>
#include <windows.h>
size_t cache_line_size() {
size_t line_size = 0;
DWORD buffer_size = 0;
DWORD i = 0;
SYSTEM_LOGICAL_PROCESSOR_INFORMATION * buffer = 0;
GetLogicalProcessorInformation(0, &buffer_size);
buffer = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION *)malloc(buffer_size);
GetLogicalProcessorInformation(&buffer[0], &buffer_size);
for (i = 0; i != buffer_size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++i) {
if (buffer[i].Relationship == RelationCache && buffer[i].Cache.Level == 1) {
line_size = buffer[i].Cache.LineSize;
break;
}
}
free(buffer);
return line_size;
}
#Elif defined(linux)
#include <stdio.h>
size_t cache_line_size() {
FILE * p = 0;
p = fopen("/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size", "r");
unsigned int i = 0;
if (p) {
fscanf(p, "%d", &i);
fclose(p);
}
return i;
}
#else
#error Unrecognized platform
#endif
#endif
Sur x86, vous pouvez utiliser l'instruction CPUID avec la fonction 2 pour déterminer diverses propriétés du cache et du TLB. L'analyse de la sortie de la fonction 2 est quelque peu compliquée, je vous renvoie donc à la section 3.1.3 de Identification du processeur Intel et instruction CPUID (PDF).
Pour obtenir ces données à partir de code C/C++, vous devez utiliser un assemblage inline, les éléments intrinsèques du compilateur ou appeler une fonction d'assemblage externe pour exécuter l'instruction CPUID.
Si vous utilisez SDL2, vous pouvez utiliser cette fonction:
int SDL_GetCPUCacheLineSize(void);
Ce qui renvoie la taille de la taille de la ligne de cache L1, en octets.
Sur mon ordinateur x86_64, en exécutant cet extrait de code:
printf("CacheLineSize = %d",SDL_GetCPUCacheLineSize());
Produit CacheLineSize = 64
Je sais que je suis un peu en retard, mais j'ajoute juste des informations pour les futurs visiteurs. La documentation SDL indique actuellement que le nombre renvoyé est en Ko, mais qu’il s’agit en réalité d’octets.
Sur la plate-forme Windows:
à partir de http://blogs.msdn.com/oldnewthing/archive/2009/12/08/9933836.aspx
La fonction GetLogicalProcessorInformation vous donnera les caractéristiques des processeurs logiques utilisés par le système. Vous pouvez parcourir l'instruction SYSTEM_LOGICAL_PROCESSOR_INFORMATION renvoyée par la fonction à la recherche d'entrées de type RelationCache. Chacune de ces entrées contient un ProcessorMask qui vous indique le ou les processeurs auxquels l'entrée s'applique, et dans CACHE_DESCRIPTOR, il vous indique le type de cache décrit et la taille de la ligne de cache pour ce cache.
ARMv6 et supérieur a C0
ou le registre de types de cache. Cependant, il n’est disponible qu’en mode privilégié.
Par exemple, à partir de Manuel de référence technique Cortex ™ -A8 :
L'objectif du registre de types de cache est de déterminer la longueur en octets de la ligne de cache d'instruction et de données, afin de permettre l'invalidation d'une plage d'adresses.
Le registre de type de cache est:
- un registre en lecture seule
- accessible uniquement dans les modes privilégiés.
Le contenu du registre de types de cache dépend de la mise en œuvre spécifique. La figure 3-2 montre la disposition des bits du registre de types de cache ...
Ne supposez pas que le processeur ARM possède un cache (apparemment, certains peuvent être configurés sans un cache). La méthode standard pour le déterminer est via C0
. Dans le ARM ARM , page B6-6:
Dans ARMv6, le registre Type de cache du coprocesseur de contrôle système est la méthode prescrite pour définir les caches L1. Voir Registre de type de cache à la page B6-14. C'est également la méthode recommandée pour les variantes antérieures de l'architecture. De plus, la section Considérations relatives aux niveaux de cache supplémentaires à la page B6-12 décrit les instructions d'architecture pour la prise en charge du cache de niveau 2.
Vous pouvez également essayer de le faire par programme en mesurant un certain timing. Évidemment, ce ne sera pas toujours aussi précis que cpuid et autres, mais il sera plus portable. ATLAS le fait à l’étape de configuration, vous voudrez peut-être le regarder: