2010-07-13 11 views
1

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.

Répondre

1

Oui, il s'agit d'une technique appelée spin lock. Notez, cependant, que le pointeur de diffusion à volatile n'est pas garanti pour fonctionner selon la norme. Déclarez simplement votre variable de verrou en tant que volatile à la place.

+0

Est-ce qu'un pointeur d'ombre qui était "volatile DWORD" fonctionne à coup sûr? – Adisak

+0

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

+0

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