web-dev-qa-db-fra.com

Alignement sur la ligne de cache et connaissance de la taille de la ligne de cache

Pour éviter un faux partage, je souhaite aligner chaque élément d'un tableau sur une ligne de cache. J'ai donc d'abord besoin de connaître la taille d'une ligne de cache, donc j'attribue à chaque élément cette quantité d'octets. Deuxièmement, je veux que le début du tableau soit aligné sur une ligne de cache.

J'utilise Linux et la plate-forme x86 à 8 cœurs. Tout d'abord, comment puis-je trouver la taille de la ligne de cache. Deuxièmement, comment puis-je m'aligner sur une ligne de cache en C. J'utilise le compilateur gcc.

Ainsi, la structure suivrait par exemple, en supposant une taille de ligne de cache de 64.

element[0] occupies bytes 0-63
element[1] occupies bytes 64-127
element[2] occupies bytes 128-191

et ainsi de suite, en supposant bien sûr que 0-63 est aligné sur une ligne de cache.

56
MetallicPriest

Pour connaître les tailles, vous devez le rechercher en utilisant la documentation du processeur, afaik il n'y a aucun moyen de le faire par programmation. Du côté positif cependant, la plupart des lignes de cache sont de taille standard, basée sur les normes Intel. Sur les lignes de cache x86 sont de 64 octets, cependant, pour éviter un faux partage, vous devez suivre les directives du processeur que vous ciblez (Intel a quelques notes spéciales sur ses processeurs basés sur Netburst), généralement vous devez vous aligner sur 64 octets pour cela (Intel indique que vous devez également éviter de franchir les limites de 16 octets).

Pour ce faire en C ou C++, vous devez utiliser la fonction standard aligned_alloc Ou l'un des spécificateurs spécifiques au compilateur tels que __attribute__((align(64))) ou __declspec(align(64)). Pour remplir les membres d'une structure pour les diviser en différentes lignes de cache, vous devez insérer un membre suffisamment grand pour l'aligner sur la prochaine limite de 64 octets

32
Necrolis

J'utilise Linux et la plate-forme x86 à 8 cœurs. Tout d'abord, comment puis-je trouver la taille de la ligne de cache.

$ getconf LEVEL1_DCACHE_LINESIZE
64

Passez la valeur en tant que définition de macro au compilateur.

$ gcc -DLEVEL1_DCACHE_LINESIZE=`getconf LEVEL1_DCACHE_LINESIZE` ...

Au moment de l'exécution, sysconf(_SC_LEVEL1_DCACHE_LINESIZE) peut être utilisé pour obtenir la taille du cache L1.

78
Maxim Egorushkin

Il n'y a aucun moyen complètement portable d'obtenir la taille de la cacheline. Mais si vous utilisez x86/64, vous pouvez appeler l'instruction cpuid pour obtenir tout ce que vous devez savoir sur le cache - y compris la taille, la taille de la ligne de cache, le nombre de niveaux, etc.

http://softpixel.com/~cwright/programming/simd/cpuid.php

(faites défiler un peu vers le bas, la page concerne SIMD, mais elle a une section pour obtenir la cacheline.)

Quant à l'alignement de vos structures de données, il n'y a également aucun moyen complètement portable de le faire. GCC et VS10 ont différentes façons de spécifier l'alignement d'une structure. Une façon de le "pirater" consiste à remplir votre structure avec des variables inutilisées jusqu'à ce qu'elle corresponde à l'alignement souhaité.

Pour aligner vos mallocs (), tous les compilateurs traditionnels ont également des fonctions malloc alignées à cet effet.

9
Mysticial

Une autre façon simple est de simplement lire/proc/cpuinfo:

cat/proc/cpuinfo | grep cache_alignment

9
Francesquini

posix_memalign ou valloc peut être utilisé pour aligner la mémoire allouée sur une ligne de cache.

8
MetallicPriest

Si quelqu'un est curieux de savoir comment faire cela facilement en C++, j'ai construit une bibliothèque avec une classe CacheAligned<T> Qui gère la détermination de la taille de la ligne de cache ainsi que l'alignement de votre objet T, référencé en appelant .Ref() sur votre objet CacheAligned<T>. Vous pouvez également utiliser Aligned<typename T, size_t Alignment> Si vous connaissez la taille de la ligne de cache au préalable, ou si vous souhaitez simplement vous en tenir à la valeur très courante de 64 (octets).

https://github.com/NickStrupat/Aligned

2
Nick Strupat