Question

Je l'ai vu une question sur pourquoi « vote est mauvais ». En termes de minimiser la quantité de temps processeur utilisé par un fil, serait-il préférable de faire une attente de spin (ie scrutin pour un changement nécessaire dans une boucle while) ou attendre sur un objet du noyau (par exemple un objet événement noyau dans Windows) ?

Pour le contexte, supposons que le code serait nécessaire pour fonctionner sur tout type de processeur, un seul coeur, hyperthreading, multi-cœurs, etc. Supposons également qu'un thread qui interrogera ou attendre ne peut pas continuer jusqu'à ce que le résultat du scrutin est satisfaisant si elle sondé au lieu d'attendre. Enfin, le temps entre le moment où un fil d'attente commence (ou interrogation) et quand la condition est satisfaite peut potentiellement varier d'un temps très court pour longtemps.

Étant donné que le système d'exploitation est susceptible de manière plus efficace « sondage » dans le cas de « attente », je ne veux pas voir le « attente signifie juste que quelqu'un d'autre ne le vote » argument, qui est de vieilles nouvelles, et pas nécessairement précis à 100%.

Était-ce utile?

La solution

A condition que le système d'exploitation a mises en œuvre raisonnables de ces types de primitives d'accès concurrentiel, il est certainement préférable d'attendre sur un objet du noyau.

Entre autres raisons, cela permet à l'OS sait pas programmer le fil en question pour que l'autres tranches de temps objet attendu, pour est dans l'état approprié. Sinon, vous avez un fil qui est constamment à être ordonnancés, mis contexte à, puis en cours d'exécution pendant un certain temps.

Vous avez demandé spécifiquement à minimiser le temps de processeur pour un fil: dans cet exemple, le fil de blocage sur un objet noyau utiliserait ZERO temps; le fil de vote utiliserait toutes sortes de temps.

En outre, le « quelqu'un d'autre vote » argument ne doit pas être vrai. Lorsqu'un objet noyau entre dans l'état approprié, le noyau peut regarder pour voir à cet instant que les discussions sont en attente pour cet objet ... puis programmer un ou plusieurs d'entre eux pour l'exécution. Il n'y a pas besoin pour le noyau (ou quelqu'un d'autre) au sondage quoi que ce soit dans ce cas.

Autres conseils

L'attente est la « plus belle » façon de se comporter. Lorsque vous attendez sur un objet votre thread noyau ne sera pas accordé de temps CPU comme il est connu par le planificateur qu'il n'y a pas de travail prêt. Votre fil ne va donner le temps processeur quand il est attendu condition est satisfaite. Ce qui signifie que vous ne serez pas inutilement monopolisant les ressources CPU.

Je pense un point qui n'a pas encore été soulevé est que si votre système d'exploitation a beaucoup de travail à faire, le blocage yeilds votre fil à un autre processus. Si tous les processus utilisent les primitives de blocage où ils devraient (comme attente du noyau, le fichier / réseau IO, etc.) que vous donnez le noyau plus d'informations pour choisir les fils doivent exécuter. En tant que tel, il fera plus de travail dans le même laps de temps. Si votre demande pourrait être en train de faire quelque chose d'utile en attendant ce fichier pour ouvrir ou le paquet pour arriver ensuite yeilding vous aidera même êtes propre application.

En attente de plus de ressources n'implique et signifie un changement de contexte supplémentaire. En effet, certaines primitives de synchronisation tels que les moniteurs CLR et Win32 sections critiques utilisent un protocole de verrouillage en deux phases - une certaine attente de rotation se fait avant de faire en fait une véritable attente

.

J'imagine faire la chose en deux phases serait très difficile, et impliquerait beaucoup d'essais et de recherche. Donc, à moins que vous avez le temps et les ressources, en tenir aux primitives fenêtres ... ils ont déjà la recherche pour vous.

Il n'y a que peu d'endroits, le plus souvent dans les choses de bas niveau OS (gestionnaires d'interruption / pilotes de périphériques) où spin-attente logique / est nécessaire. applications à usage général sont toujours mieux en attente sur des primitives de synchronisation comme mutex / variables / sémaphores conditionnelles.

Je suis d'accord avec Darksquid, si votre système d'exploitation a des primitives d'accès concurrentiel décent, alors vous ne devriez pas avoir au sondage. sondages vient habituellement dans son propre sur les systèmes en temps réel ou matériel restreint qui ne dispose pas d'un système d'exploitation, alors vous devez interroger, parce que vous pourriez ne pas avoir la possibilité d'attendre (), mais aussi parce qu'il vous donne un contrôle grain fin sur exactement combien de temps vous voulez attendre dans un état particulier, plutôt que d'être à la merci du planificateur.

En attente (blocage) est presque toujours le meilleur choix ( « meilleur » au sens de l'utilisation efficace des ressources de traitement et de minimiser l'impact à tout autre code en cours d'exécution sur le même système). Les principales exceptions sont les suivantes:

  1. Lorsque la durée du scrutin prévu est faible (même ordre de grandeur du coût du syscall de blocage).
  2. La plupart du temps dans les systèmes embarqués, lorsque la CPU est dédiée à l'exécution d'une tâche spécifique et il n'y a aucun avantage à avoir ralenti CPU (par exemple certains routeurs logiciels construits dans les années 90 « utilisé cette approche.)

Polling est généralement pas utilisé dans les noyaux OS pour mettre en œuvre le système de blocage des appels -. À la place, des événements (interruptions, minuteries, actions sur les mutex) se traduisent par un processus bloqué ou fil étant fait runnable

Il existe quatre approches de base on peut prendre:

  1. Utilisez une OS attente primitive attendre jusqu'à ce que l'événement se produit
  2. Utilisez une minuterie OS primitive pour vérifier à un taux défini si l'événement a eu lieu encore
  3. vérifier et revérifier si l'événement a eu lieu, mais utiliser une primitive OS pour obtenir une tranche de temps pour une durée arbitraire et inconnue en tout temps, il n'a pas.
  4. vérifier et revérifier si l'événement a eu lieu, sans céder la CPU si elle n'a pas.

# 1 est pratique, il est souvent la meilleure approche à moins de retarder sa réponse à l'événement pourrait être bénéfique. Par exemple, si l'on prévoit recevoir une grande quantité de données de port série au cours de quelques secondes, et si le traitement 100ms de données après son envoi sera tout aussi bon que le traitement instantanément, une interrogation périodique en utilisant l'un des deux derniers approches pourraient être mieux que la mise en place d'un événement « données reçues ».

Approche n ° 3 est assez grossière, mais peut dans de nombreux cas être un bon. Il sera souvent perdre plus de temps CPU et de ressources que approcherait # 1, mais il sera dans de nombreux cas, être plus simple à mettre en œuvre et le gaspillage des ressources dans de nombreux cas être assez petit pas à la matière.

Approche # 2 est souvent plus compliqué que # 3, mais a l'avantage d'être en mesure de gérer de nombreuses ressources avec une seule minuterie et sans fil dédié.

Approche n ° 4 est parfois nécessaire dans les systèmes embarqués, mais est généralement très mauvais à moins que l'on est directement le matériel de vote et n'aura rien d'utile à faire jusqu'à ce que l'événement en question se produit. Dans de nombreux cas, il ne sera pas possible pour la condition d'être attendu à se produire jusqu'à ce que le fil attendant qu'il donne la CPU. Cédant la CPU dans l'approche # 3 permettra en fait le fil d'attente pour voir l'événement plus tôt que ne monopolisant il.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top