Plusieurs threads et de cache du PROCESSEUR
Je mets en place un filtrage des images de l'opération en C en utilisant plusieurs threads et de le rendre le plus rationnellement possible. J'ai une question cependant: Si une mémoire est accessible par thread-0, et en même temps si la mémoire est accessible par thread-1, il va l'obtenir à partir de la mémoire cache ? Cette question découle de la possibilité que ces deux threads peuvent être en cours d'exécution dans deux différents cœurs du PROCESSEUR. Donc, une autre façon de mettre c'est: tous les cœurs partagent la même mémoire cache ?
Supposons que j'ai une disposition de la mémoire comme suit
int de sortie[100];
Supposons qu'il y ait 2 cœurs du PROCESSEUR, et donc je frayer les deux fils de travailler simultanément. Un tel programme pourrait être de diviser la mémoire en deux morceaux, 0 à 49 et de 50 à 99 et de laisser chaque thread de travail sur chaque morceau. Une autre façon serait de laisser thread-0 travailler sur des indices, comme 0 2 4 et ainsi de suite.. alors que l'autre thread de travail sur les indices comme 1 3 5 .... Plus tard la technique est plus facile à mettre en œuvre (spécialement pour les données 3D) mais je ne suis pas sûr si je pouvais utiliser le cache efficacement de cette façon.
- En fin de compte, cette connaissance ne vous aidera pas beaucoup. Même si je suis d'accord que le fait d'être capable d'interpréter les observations en conséquence à la connaissance de la CPU entrailles est bon, en fin de compte vous êtes à la mesure de ce qui est plus rapide, et d'appliquer ce que vous avez observé, peu importe si il s'adapte à toute théorie.
- Je ne vois pas pourquoi cela a un
c++
tag (vous l'avez fait écrire, dans C, vous l'avez dit), donc je l'ai enlevé. N'hésitez pas à crier à moi si c'était stupide.
Vous devez vous connecter pour publier un commentaire.
En général, c'est une mauvaise idée de partager le chevauchement des régions de la mémoire comme si un thread processus 0,2,4... et les autres processus 1,3,5... Bien que certaines architectures peuvent supporter, la plupart des architectures de ne pas, et vous ne pourrez probablement pas spécifier sur quelles machines votre code s'exécute. Aussi l'OS est libre d'affecter votre code de tout cœur qu'il aime (un seul, deux sur le même processeur physique, ou les deux cœurs de processeurs séparés). Aussi chaque PROCESSEUR a généralement séparée de la première mémoire cache de niveau, même si elle est sur le même processeur.
Dans la plupart des situations 0,2,4.../1,3,5... va ralentir les performances de très haut pour éventuellement être plus lent qu'un seul PROCESSEUR.
Herbe Sutters "Éliminer Les Faux Partage" le démontre très bien.
À l'aide de la formule [...n/2-1] et [n/2...n] à l'échelle beaucoup mieux sur la plupart des systèmes. Il peut même conduire à des super-linéaire des performances que la taille du cache de tous les Processeurs en somme qui peut être utilisé. Le nombre de threads utilisés doivent toujours être configurable et par défaut, le nombre de cœurs de processeur trouvé.
La réponse à cette question dépend étroitement de l'architecture et du niveau de cache, où les fils sont en fait en cours d'exécution.
Par exemple, de récentes Intel multi core CPUs ont une L1 caches qui sont par coeur, et un cache L2 partagé entre les cœurs qui sont dans le même CPU package; cependant différents packages de PROCESSEUR ont leurs propres caches L2.
Même dans le cas où votre threads en cours d'exécution sur deux cœurs dans un paquet, si deux threads d'accéder à des données dans le même cacheline vous aurez cacheline rebondir entre les deux caches L1. Cette est très inefficace, et vous devez concevoir un algorithme pour éviter cette situation.
Quelques commentaires ont posé des questions sur la façon d'aller sur la façon d'éviter ce problème.
À cœur, c'est vraiment pas très compliqué, mais juste pour éviter les deux threads simultanément en essayant d'accéder à des données qui se trouve sur la même ligne de cache, où au moins un thread d'écriture de données. (Aussi longtemps que tous les threads ne sont lecture les données, il n'y a pas de problème sur la plupart des architectures, des données en lecture seule peuvent être présents dans plusieurs caches).
Pour ce faire, vous devez connaître la taille de ligne de cache - ceci varie en fonction de l'architecture, mais actuellement la plupart des x86 et x86-64) de la famille des puces utiliser un de 64 octets par ligne de cache (consultez votre manuel de l'architecture pour d'autres architectures). Vous aurez également besoin de connaître la taille de vos structures de données.
Si vous demandez à votre compilateur pour aligner la structure de données partagées de l'intérêt pour un 64 frontière d'octet (par exemple, votre tableau
output
), alors vous savez qu'il va commencer au début d'une ligne de cache, et vous pouvez également calculer lorsque la nouvelle ligne de cache frontières. Si votreint
est de 4 octets, chaque cacheline contiendra exactement 8int
valeurs. Tant que le tableau commence sur un cacheline limite, alorsoutput[0]
paroutput[7]
sera sur une ligne de cache, etoutput[8]
paroutput[15]
sur la prochaine. Dans ce cas, vous devez concevoir un algorithme de telle sorte que chaque thread travaille sur un bloc adjacentint
valeurs qui est un multiple de 8.Si vous stockez compliqué
struct
types plutôt que la plaineint
, lepahole
l'utilitaire d'utilisation. Il permettra d'analyser lesstruct
types dans votre binaire compilé, et de vous montrer la mise en page (y compris rembourrage) et la taille totale. Vous pouvez ensuite ajuster votrestruct
s à l'aide de cette sortie, par exemple, vous pouvez manuellement ajouter un peu de rembourrage, de sorte que votrestruct
est un multiple de la taille de ligne de cache.Sur les systèmes POSIX, le
posix_memalign()
fonction est utile pour allouer un bloc de mémoire avec un certain alignement.y_size * x_size
serait un multiple de 8.J'ai peut-être de confondre, mais si le cœur du cache est partagé ou non dépend de la mise en œuvre de la CPU. Vous devez examiner les fiches techniques du fabricant pour vérifier si chaque core de votre CPU dispose de son propre cache ou que le cache a été partagé.
Je travaillais sur la manipulation d'image aussi bien pour une entreprise de sécurité et, parfois, nous avons obtenu des images corrompues après l'exécution d'opérations de traitement sur les threads. Après de longues investigations nous en sommes venus à la conclusion que le cache a été partagé entre la CPU Core et que dans de rares cas, les données étant écrasé ou remplacées avec des données erronées.
Si c'est quelque chose à prendre en compte ou est plutôt un événement rare je ne peux pas répondre.
Documentation Intel
Intel publie par la génération de fiches techniques qui peuvent contenir ce genre d'informations.
Par exemple, pour le processeur i5-3210M qui j'avais sur mon ancien ordinateur, je regarde la 3ème génération - feuille de données du Volume 1 3.3 "Intel Hyper-Threading Technology (Technologie Intel hyper-threading)" dit:
qui confirme que les caches sont partagés dans un hyperthread pour cette génération de Processeurs.
Voir aussi: