System.YieldProcessor

De RAD Studio API Documentation
Aller à : navigation, rechercher

Delphi

procedure YieldProcessor;

Propriétés

Type Visibilité  Source Unité  Parent
procedure public System.pas System System

Description

Fournit au processeur un conseil affichant que le code en cours est dans une boucle d'attente.

La routine YieldProcessor améliore les performances des boucles d'attente, en fournissant au processeur un conseil affichant que le code en cours est dans une boucle d'attente.

Une boucle d'attente est un moyen de retarder l'exécution d'un thread sans céder le contrôle du thread au système d'exploitation, qui doit ainsi entrer son planificateur et choisir un autre thread à exécuter. Si le système d'exploitation entre son planificateur, cela signifie un changement de contexte, qui implique :

  • L'enregistrement du contexte du thread (état des registres CPU, etc.)
  • Une transition du noyau, du mode utilisateur au mode noyau
  • La sélection d'un nouveau thread à exécuter et le chargement de son contexte
  • Une transition du noyau, du mode noyau au mode utilisateur
  • Tous les états du cache CPU, le tampon de prédiction des branches (aussi appelé tableau de l'historique des branches), les tampons de traduction TLB (Translation Lookaside Buffer) pour la mise en cache des mappages des pages mémoire virtuelles, et ainsi de suite, qui vous ont aidé à rendre le code du thread en cours plus "réactif" et plus rapide d'exécution, sont perdus quand le nouveau thread est entièrement enlevé probablement d'un processus complètement différent.

Si le délai attendu du thread est petit, plus petit qu'une tranche de thread (de l'ordre de quelques millisecondes), il est alors logique d'éviter les coûts d'un changement de contexte et d'attendre à l'aide d'une boucle d'attente, plutôt que de céder le thread (en appelant, par exemple, la fonction Win32 Sleep() avec 0 en argument).

De tels cas se produisent lors de l'utilisation de primitives de synchronisation et de techniques libres de verrous. Par exemple, une primitive de synchronisation en mode utilisateur peut être implémentée par un test conditionnel atomique et une opération d'ensemble telle que InterlockedCompareExchange. Pour modifier correctement et d'une manière fiable l'état d'une variable partagée par les threads où le nouvel état de la variable dépend d'une certaine façon de son état antérieur, vous devez utiliser une primitive de synchronisation fournie par le système d'exploitation, ou un "test-and-set" atomique dans une boucle. L'utilisation de la primitive de synchronisation fournie par le système d'exploitation signifie l'induction d'un changement de contexte en cas de conflit. Un "test-and-set" atomique dans une boucle échoue simplement à chaque fois qu'un conflit se produit ; vous bouclez donc et réessayez. Mais si vous réessayez trop tôt, une grande activité peut se produire, étant que les autres threads qui interfèrent sont toujours occupés. Vous souhaitez donc attendre suffisamment pour augmenter la probabilité de déplacement des autres threads ; d'où une boucle d'attente.

Avertissement :  Lors de la recherche d'amélioration des performances à l'aide de boucles d'attente et de techniques libres de verrous, vous pouvez introduire un risque assez important d'erreurs en retour, pour des chances moyennes de gains de performances.

Voir aussi