J'ai une grande structure de données qui utilise la segmentation pour réduire les conflits de verrous. En ce moment j'utilise des serrures de système mais 99,99% du temps, le verrou est incontesté et de plus, la quantité de temps tenant le verrou est tout à fait minuscule. Cependant, plusieurs opérations de mémoire distinctes sont effectuées pendant que le verrou est maintenu. Il est en fait arrivé au point où le temps consacré à l'acquisition et à la libération des verrous est important par rapport à l'accès global à la structure de données. Je pense donc à remplacer le verrou du système d'exploitation par le verrou très simple suivant. Seulement essayer et déverrouiller sont montrés ici parce que 99.99% du temps FastTryLock() réussira. La variable "pLock" représente ici un verrou de granularité fine dans la structure striée.Cette implémentation Fast Atomic Lock peut-elle fonctionner?
J'ai écrit la mise en œuvre suivante qui semble bien fonctionner mais j'apprécierais la confirmation si elle est correcte ou incorrecte.
bool FastTryLock(DWORD *pLock)
{
if(0==AtomicXCHG(pLock,1)) {
MemoryBarrier_LightWeight(); return(true);
}
return(false);
}
void FastUnlock(DWORD *pLock)
{
MemoryBarrier_LightWeight(); *((volatile DWORD*)pLock)=0;
}
Sur le PC, MemoryBarrier_LightWeight() est un non-op puisque la garantie CPU commande d'écriture de la mémoire.
Est-ce qu'un pointeur d'ombre qui était "volatile DWORD" fonctionne à coup sûr? – Adisak
Aussi, la différence entre ceci et le "spin lock" que vous liez est que j'utilise seulement l'op Interlocked pour acquérir le verrou. La sémantique de l'escrime de mémoire devrait être suffisante pour le libérer. – Adisak
Je ne peux pas analyser le langage cauchemar de la norme C++, mais dans les implémentations du monde réel, la variable 'volatile' fonctionnera exactement comme vous le souhaitez. L'optimisation que vous avez décrite dans le deuxième commentaire est également mentionnée dans l'article lié. Notez que les types atomiques font partie du standard C++ 0x, donc vous pouvez utiliser par exemple. 'std :: atomic_flag' si votre compilateur le supporte et évite le codage manuel. – doublep