Question

Dans quelles circonstances est-il dangereux d’avoir deux threads différents écrivant simultanément sur des éléments adjacents du même tableau sur x86? Je comprends que sur certaines architectures de type DS9K avec des modèles de mémoire insensés, cela peut causer la déchirure des mots, mais que sur x86, les octets simples sont adressables. Par exemple, dans le langage de programmation D, real est un type à virgule flottante de 80 bits sur x86. Serait-il prudent de faire quelque chose comme:

real[] nums = new real[4];  // Assume new returns a 16-byte aligned block.
foreach(i; 0..4) {
    // Create a new thread and have it do stuff and 
    // write results to index i of nums.
}

Remarque: je sais que même si cela est sûr, cela peut parfois causer de faux problèmes de partage avec le cache, ce qui ralentit les performances. Toutefois, pour les cas d’utilisation auxquels je pense, les écritures seront assez rares pour que cela n’ait pas d’importance dans la pratique.

Éditer: Ne vous inquiétez pas pour la relecture des valeurs écrites. L'hypothèse est qu'il existera une synchronisation avant la lecture des valeurs. Je me soucie seulement de la sécurité de l'écriture de cette manière.

Était-ce utile?

La solution

Le x86 a des caches cohérents. Le dernier processeur à écrire sur une ligne de cache acquiert l'intégralité et effectue une écriture sur le cache. Cela garantit que les valeurs à un octet et à 4 octets écrites sur les valeurs correspondantes sont mises à jour de manière atomique.

C’est différent de "son coffre-fort". Si les processeurs n'écrivent chacun qu'en octets / DWORDS, "en possession de" " par ce processeur par la conception, les mises à jour seront correctes. En pratique, vous voulez qu'un processeur lise les valeurs écrites par d'autres, ce qui nécessite synchronisation.

Il est également différent de ce qu’il est "efficace". Si plusieurs processeurs peuvent chacun écrire à différents endroits de la ligne de cache, celle-ci peut effectuer un ping-pong entre les processeurs, ce qui coûte beaucoup plus cher que si la ligne de cache passe à un seul processeur et y reste. La règle habituelle est de placer les données spécifiques au processeur dans sa propre ligne de cache. Bien sûr, si vous n'écrivez que pour un mot, juste une fois, et la quantité de travail est importante par rapport à un déplacement de ligne de cache, puis votre performance sera acceptable.

Autres conseils

Il se peut que je manque quelque chose, mais je ne prévois aucun problème. L’architecture x86 écrit uniquement ce dont elle a besoin, elle ne fait aucune écriture en dehors des valeurs spécifiées. Cache-snooping gère les problèmes de cache.

Vous parlez des spécificités de x86, mais votre exemple est dans un langage de haut niveau. Votre question spécifique à propos de D ne peut être répondue que par les personnes qui ont écrit le compilateur que vous utilisez, ou peut-être la spécification du langage D. Java, par exemple, exige que l’accès à l’élément de tableau ne provoque pas de déchirement.

En ce qui concerne x86, le caractère atomique des opérations est spécifié à la section 8.1 du Manuel du développeur Intel, volume 3A . Selon lui, les opérations de stockage atomique incluent: stocker un octet, stocker un mot aligné par mot et un mot aligné dword sur tous les processeurs x86. Il indique également que, sur les processeurs P6 et ultérieurs, les accès non alignés de 16, 32 et 64 bits à la mémoire en cache d'une ligne de cache sont atomiques.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top