Est-ce que spinlock et polling sont la même chose?
Wikipédia:
un spinlock est un verrou qui fait qu'un thread essayant de l'acquérir attend simplement dans une boucle ("spin") tout en vérifiant à plusieurs reprises si le verrou est disponible
Cela ressemble énormément à:
while(!ready);
On m'a appris à éviter les sondages autant que possible car c'était complètement sous-optimal. Alors, spinlock est-il un nom de fantaisie pour les mauvais vieux sondages? En quoi un spinlock est-il différent d'un sondage?
L'interrogation fait référence à la vérification répétée si une ressource (n'importe quelle sorte de ressource) est prête.
Un verrou tournant est lorsque la ressource que vous interrogez est un verrou.
Notez que l'interrogation est pas mauvaise. En particulier, l'interrogation est efficace lorsqu'il y a généralement des données prêtes lorsque vous interrogez. L'interrogation n'est inefficace que si vous le faites sans obtenir de données en retour.
D'un autre côté, 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 réellement 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 a été configuré pour m'interrompre à chaque fois qu'un nouveau courrier électronique arrive. Ce qui arrivait une ou deux fois par semaine. Vérifier constamment ma boîte de réception aurait été une perte de temps colossale.
Aujourd'hui, 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 e-mails. L'interrogation est désormais beaucoup plus efficace.
Les verrous tournants sont efficaces lorsque a) la probabilité que le verrou est pris est faible, et b) si le verrou est pris, il ne sera maintenu que pendant une courte période. En d'autres termes: il est efficace pour les verrous à grains fins pour la plupart non contestés, mais inefficace pour les verrous à grains grossiers très contestés.
(Et bien sûr, les verrous tournants ne fonctionnent que lorsqu'il y a un vrai parallélisme, sinon l'autre thread n'aura pas la possibilité de libérer le verrou. Je suppose que c'est assez évident, mais je voulais quand même le déclarer.)
Un verrou tournant est un type de verrou, en particulier, celui obtenu via polling.
L'interrogation est une méthode de vérification du statut de quelque chose (en demandant le statut, au lieu d'attendre qu'on lui dise le statut).
L'interrogation n'est pas toujours un verrou tournant, par exemple, l'interrogation de l'état des touches du clavier.
De plus, le sondage n'est pas intrinsèquement mauvais. Très de courtes périodes d'interrogation peuvent éviter des changements de contexte coûteux qui nécessiteraient l'utilisation d'interruptions, sans oublier que l'interrogation peut parfois être plus simple à mettre en œuvre et donc plus facile à maintenir, en particulier à des niveaux inférieurs. Comme d'habitude, les absolus sont une chose terrible, et vous devez utiliser la méthode qui offre le compromis performance/complexité approprié à vos besoins comme vous les avez mesurés, plutôt que d'utiliser ou d'éliminer aveuglément les options.
Spinlock est différent de l'interrogation car il ne se produit que pour une très courte période de temps, de l'ordre de quelques millisecondes ou moins. Le scrutin peut se poursuivre indéfiniment.
En programmation parallèle, un bref épisode de rotation est souvent préférable au blocage, car il évite le coût de la commutation de contexte et des transitions du noyau.
Lectures complémentaires
SpinLock et SpinWait en C #
Spinlocks et verrous en lecture-écriture en C
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 pensez qu'une ressource ne sera verrouillée que très peu de temps - par exemple si un verrou n'est utilisé que pour mettre à jour une variable. Le verrou tournant interroge le verrou à la vitesse maximale, mais, espérons-le, pendant moins de microsecondes. Un mutex normal nécessiterait un appel OS. SI le verrou n'est maintenu que pendant une petite période, le verrou tournant n'utilise qu'une petite quantité de temps CPU, tandis que l'appel du système d'exploitation prendra plus de temps. Mais si cette attente est fausse, le verrou tournant est très inefficace - il utilisera 100% du temps CPU sur un processeur, tandis que le mutex normal ne prend que le temps d'entrer dans le système d'exploitation et de revenir.
Parfois, les deux sont combinés; vous exécutez le verrouillage de rotation pendant une courte période et passez à une stratégie différente si le verrouillage de rotation ne fonctionne pas.
Une interrogation excessive est quelque chose que vous ne devez pas faire car elle gaspille les ressources système. Il s'ensuit que l'interrogation est très bien si elle ne gaspille pas les ressources système.
Par exemple, une interrogation excessive obtiendra une charge CPU à 100% dans les cas où le travail réel n'entraînerait qu'une charge de 2%.
L'interrogation peut être utilisée 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érifiera au plus une fois toutes les 15 millisecondes, c'est donc une vérification tous les ~ 20 millions de cycles d'horloge. Ce type de sondage est formidable, car il ne gaspille pas les ressources du système.
Un SpinLock est pas un cas spécial. Si nous avons un SpinLock et qu'un thread entre dans le verrou et qu'un autre doit attendre, le SpinLock n'est pas le bon choix si et seulement si le thread en attente gaspille les ressources système. Le thread en attente gaspillera les ressources du système si et seulement s'il doit attendre un certain temps avant d'acquérir le verrou.
Par conséquent, l'utilisation d'un SpinLock pour protéger tout ce qui nécessite quelques milliers de cycles d'horloge ou plus avant de se déverrouiller à nouveau (par exemple, compiler et exécuter un morceau de javascript à la volée) est mauvaise, 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, c'est bien parce que le thread en attente ne tournera que 2 ou 3 fois et ne gaspillera donc pas les ressources système.