Quelle est la différence entre spinlock et polling?

41

Est-ce que spinlock et polling sont la même chose?

Wikipédia:

un spinlock est un verrou qui oblige un thread à l'acquérir à attendre simplement dans une boucle ("spin") tout en vérifiant à plusieurs reprises si le verrou est disponible

Cela ressemble beaucoup à:

while(!ready);

On m'avait appris à éviter les scrutins chaque fois que c'était possible, car cela était complètement sous-optimal. Alors, est-ce que spinlock est un nom de fantaisie pour le mauvais vieux scrutin? En quoi un spinlock est-il différent du polling?

Seigneur Loh.
la source

Réponses:

85

Une interrogation consiste à vérifier à plusieurs reprises si une ressource ( tout type de ressource) est prête.

Un spinlock se produit lorsque la ressource que vous interrogez est un verrou.

Notez que l'interrogation n'est pas mauvaise. En particulier, l'interrogation est efficace lorsque des données sont généralement prêtes lorsque vous interrogez. La scrutation n'est inefficace que si vous le faites sans récupérer aucune donnée en retour.

D'autre part, les interruptions sont inefficaces s'il y a tellement de données que vous êtes constamment interrompu. Ils sont efficaces si les données arrivent assez rarement pour que vous puissiez effectuer un travail utile avant d'être interrompu.

Je peux vous donner un exemple concret de ma propre expérience: il y a 15 ans, mon programme de messagerie électronique était configuré pour m'interrompre chaque fois qu'un nouveau courrier électronique arrivait. Ce qui se produisait une ou deux fois par semaine. Vérifier constamment ma boîte de réception aurait été une perte de temps colossale.

De nos jours, toutes les notifications sont désactivées. Je sais que chaque fois que je regarde dans ma boîte de réception, il y aura de nouveaux courriels. Le vote est beaucoup plus efficace maintenant.

Les verrous sont efficaces lorsque a) la probabilité que le verrou soit utilisé est faible et b) si le verrou est utilisé, il ne sera maintenu que pendant une courte période. En d'autres termes: il est efficace pour la plupart des verrous à grain fin non contrôlés, mais inefficace pour les verrous à grain grossier très dispendieux.

(Et bien sûr, les spinlocks ne fonctionnent que lorsqu'il y a un vrai parallélisme, sinon l'autre thread n'aura aucune chance de libérer le verrou. Je suppose que c'est assez évident, mais je voulais quand même le préciser.)

Jörg W Mittag
la source
5
Les spinlocks peuvent être parfaitement adaptés dans un environnement multitâche coopératif. Vous devez juste vous assurer que vous cédez le contrôle dans la boucle.
Kevin
4
Excellent exemple avec des emails. Ca me rappelle que tu as toujours un email ...
Petr Pudlák
2
@ Kevin: J'ai une idée très puriste d'un spinlock, littéralement un verrou qui tourne dans une boucle vide. ( atomically_do { while (lock.is_locked?); lock.acquire! }) Si cela cède, ce n'est pas une boucle vide et donc pas un spinlock dans cette vision puriste :-D Mais bien sûr, une hybridation avec d'autres types de verrous ou de relaxations / ajouts à l'idéal platonique est parfaitement logique dans le monde réel.
Jörg W Mittag
3
@bubakazouba: Un spinlock fonctionne littéralement en "tournant" dans une boucle vide et en vérifiant "Le verrou est-il relâché? Le verrou est-il libéré? Le verrou est-il libéré? Le verrou est-il libéré? Le verrou est-il relâché?" encore et encore. S'il n'y a pas de parallélisme, il n'y a pas d'autre thread en même temps qui pourrait libérer le verrou, vous avez donc une boucle sans fin! Voir le commentaire directement au-dessus du vôtre.
Jörg W Mittag
1
@kasperd: Vous pouvez toujours voir le multitâche coopératif dans un logiciel de serveur basé sur les événements tel que nginx. Dans ce cas, il y a un thread et pas de verrouillage, ce qui signifie que vous ne pouvez exploiter qu'un seul noyau. À ma connaissance, il n’existe littéralement aucun exemple concret de véritable multitâche coopératif multicœur. Un tel système serait stupide, car vous auriez tous les inconvénients du multitâche coopératif sans les avantages de l'absence de verrouillage.
Kevin
10

Un spinlock est un type de verrou, plus précisément obtenu par interrogation.

L’interrogation est une méthode de vérification de l’état de quelque chose (en demandant l’état, par opposition à attendre d’être informé de l’état).

Toutes les interrogations ne sont pas des verrouillages, par exemple, interroger l'état des touches du clavier.


De plus, les sondages ne sont pas mauvais en soi. De très courtes périodes d'interrogation peuvent éviter des décalages de contexte coûteux liés à l'utilisation d'interruptions, sans oublier que l'interrogation peut parfois être plus simple à mettre en œuvre et donc plus facile à gérer, en particulier aux niveaux les plus bas. Comme d'habitude, les absolus sont une chose terrible, et vous devriez utiliser la méthode qui donne le compromis performance / complexité approprié pour vos besoins tels que vous les avez mesurés , plutôt que d'utiliser aveuglément ou de rejeter des options.

8bittree
la source
5

Le spinlock est différent de l'interrogation, car il ne se produit que pendant une très courte période, de l'ordre de quelques millisecondes ou moins. Le vote peut durer indéfiniment.

En programmation parallèle, un bref épisode de rotation est souvent préférable au blocage, car il évite les coûts liés au changement de contexte et aux transitions du noyau.

Lectures complémentaires
SpinLock et SpinWait en C #
Spinlocks et verrous en lecture-écriture en C

Robert Harvey
la source
Je pense que vous vouliez dire microsecondes. Pour un verrou d'une milliseconde entière, nous devrions utiliser une implémentation de verrou qui appelle le noyau en cas de conflit.
Peter
@ Peter Peut-être que c'est ce que Albahari voulait dire. C'est ce que dit son texte.
Robert Harvey
4

La différence est qu’un spinlock n’est (espérons-le) utilisé que dans les situations où il est approprié, et dans ces situations, il est très efficace.

Vous utilisez un verrou tournant si vous prévoyez qu'une ressource ne sera verrouillée que pendant un très court instant, par exemple si un verrou est utilisé uniquement pour mettre à jour une variable. Le spinlock interroge le verrou à la vitesse maximale, mais dans l’espoir moins de quelques microsecondes. Un mutex normal nécessiterait un appel sur le système d'exploitation. SI le verrou n'est maintenu que pendant un temps très court, le spinlock ne consomme que très peu de temps CPU, alors que l'appel du système d'exploitation prend plus de temps. Mais si cette attente est fausse, le spinlock est très inefficace - il utilisera 100% de temps de calcul sur un processeur, tandis que le mutex normal ne prend que le temps nécessaire pour entrer dans le système d’exploitation et y revenir.

Parfois, les deux sont combinés; vous exécutez le verrouillage du spin pendant une courte période et passez à une stratégie différente si le spinlock ne fonctionne pas.

gnasher729
la source
2

Les sondages excessifs ne doivent pas être utilisés car ils gaspillent des ressources système. Il s'ensuit que le vote est correct s'il ne gaspille pas de ressources système .

Par exemple, une interrogation excessive entraînera une charge du processeur de 100% dans les cas où le travail réel n'entraînerait qu'une charge de 2%.

Le sondage peut être utilisé pour autre chose que while(!ready). Par exemple, cela signifie vérifier régulièrement si l'utilisateur a appuyé sur une touche. Une implémentation saine vérifie au plus une fois toutes les 15 millisecondes. Un contrôle tous les 20 millions de cycles environ. Ce type de sondage est excellent, car il ne gaspille pas de ressources système.

Un SpinLock n'est pas un cas particulier. Si nous avons un SpinLock et qu'un thread entre dans le verrou, et qu'un autre doit attendre, SpinLock est le mauvais choix si et seulement si le thread en attente gaspille des ressources système. Le thread en attente gaspille les ressources du système si et seulement si il doit attendre un laps de temps important avant de pouvoir obtenir le verrou.

Par conséquent, utiliser un SpinLock pour protéger tout ce qui nécessite quelques milliers de cycles d'horloge ou plus avant qu'il ne se débloque à nouveau (par exemple, compiler et exécuter un morceau de javascript à la volée) est mauvais, exactement pour la raison que vous avez indiquée. Mais utiliser un SpinLock pour protéger quelque chose qui se termine rapidement, comme accéder à une carte de hachage correctement implémentée est acceptable, car le thread en attente ne tourne que 2 ou 3 fois et ne gaspille donc pas de ressources système.

Peter
la source