J'ai testé les performances de Slim Reader / Serrure Writer sous Windows 7 à l'aide du codeFrom Windows via C / C ++ em>. Le résultat m'a surpris que la performance de verrouillage exclusive. Voici le code et le résultat. P> Pourriez-vous expliquer pourquoi cela pourrait arriver? p> p> g_value code> est une variable globale volatile int. P>
p>
3 Réponses :
spéculation: p>
Le verrou exclusif est le cas plus simple. Les verrous partagés permettent un parallélisme mais doivent faire face aux possibilités de famine afin qu'il y a des frais généraux supplémentaires. P>
Il s'agit d'un résultat assez courant pour les petits verrouilles à usage général (comme des srwlocks, qui ne sont qu'un pointeur de taille). P>
En outre, l'argument de Raymond Chen sur la conflit sur G_Value est également vrai. Si G_Value a été lu au lieu d'écrit dans les deux cas, vous remarquerez peut-être un avantage pour le verrou partagé. P>
Détails: strong> p>
La serrure SRW est mise en œuvre à l'aide d'une seule variable atomique de pointe pouvant prendre un certain nombre d'états différents, en fonction des valeurs des bits faibles. La description de la manière dont ces bits sont utilisées est hors de portée de ce commentaire - le nombre de transitions de l'état est assez élevé - donc je ne mentionnerai que quelques états que vous pouvez rencontrer dans votre test. P >
Etat de verrouillage initial: strong> (0, Controlbits: 0) - Un verrou de SRW démarre avec tous les bits réglés sur 0. P>
État partagé: strong> (SHARCOUNT: N, Controlbits: 1) - Lorsqu'il n'y a pas d'acquérir exclusif contradictoire et que le verrou est détenu, le nombre d'actions est stocké directement dans la variable de verrouillage. < / p>
Etat exclusif: strong> (SHARCOUNT: 0, Controlbits: 1) - Lorsqu'il n'y a pas d'acquérir partagé en conflit ou d'acquérir exclusif, la serrure a un jeu de bits bas et rien d'autre. P>
Dans ce schéma, essayant d'acquérir une serrure exclusive lorsque vous ne savez pas que l'état initial est une seule écriture sur le mot de verrouillage, pour définir le bit bas et récupérer l'ancienne valeur (celle-ci peut être effectuée sur x86 avec un Lock BTS Instruction). Si vous avez réussi (comme vous le ferez toujours dans le boîtier de thread), vous pouvez procéder à la région verrouillée sans autre opération. P>
essayer d'acquérir un verrou partagé est une opération plus impliquée: vous devez d'abord lire la valeur initiale de la variable de verrouillage pour déterminer l'ancien nombre d'actions, incrémentez le nombre de partage que vous avez lu, puis écrivez la valeur mise à jour en conditionnellement avec l'instruction LOCK CMPXCHG. Il s'agit d'une chaîne sensiblement plus longue d'instructions dépendantes de la série. Il est donc plus lent. De plus, CMPXCGH est un peu plus lent sur de nombreux processeurs que les instructions atomiques inconditionnelles telles que le verrouillage BTS. P>
Il serait possible en théorie d'accélérer la première acquisition partagée d'une serrure en supposant que la serrure était dans son état initial au début et effectuant la serrure CMPXCHG en premier. Cela accélérerait l'acquisition initiale partagée de la serrure (toutes dans votre cas à une seule-thread), mais cela ralentirait considérablement les cas où la serrure est déjà détenue partagée et une deuxième acquisition partagée survient. P>
Un ensemble similaire d'opérations divergentes se produit lorsque le verrou est libéré, le coût supplémentaire de la gestion de l'état partagé est également payé sur le côté reliésRwockshared. p>
Un développeur de noyau Windows consacré à l'optimisation des verrous dans Windows m'a dit en ce qui concerne la performance en règle générale: P>
Évidemment, il y a d'autres aspects sur les verrous que l'on devrait envisager: p>
Alors oui, il suffit de favoriser CS sauf si vous y lit >>>> écrit. P>
Combien d'instances de fil testez-vous?
@Djna: J'ai testé avec 1,2,4 threads comme indique le résultat.
La différence entre
42ms code> et50ms code> dans le cas d'un thread ressemble à une gigue raisonnable pour moi - augmentez le nombre d'échantillons pour obtenir des mesures plus précises.@Jandvorak: Désolé mais je ne peux pas te chercher. Voulez-vous dire que le résultat du mutex one est faux?
@Jandvorak: J'ai augmenté le nombre de threads à 64, le résultat se tourne vers 2999 ms (Slim Reader / Writer Exclusive) vs 5450ms (Slim Reader / Writer partagé).
La serrure partagée devrait être beaucoup plus rapide si la serrure reste verrouillée pendant un certain temps - et c'est le but de celui-ci; permettre l'accès partagé.
Le verrouillage partagé a la conflit sur
g_value code>. Le verrou exclusif ne le fait pas. En raison de la verrouillage injustice, la version exclusive permet un thread exécuter de nombreuses itérations (conserver la propriété deg_value code> tout au long). La version partagée oblige la propriété deg_value code> pour rebondir entre les noyaux constamment.