Multicœur et synchronisation

Si le code ci-dessus est exécuté simultanément par deux threads, la valeur finale de counter peut être inférieure à 200000. Pour quelle raison ?

int counter = 0;
// 2つのスレッドが同時に、それぞれ
for (int i = 0; i < 100000; i++)
    counter++;
  1. ALe CPU se trompe parfois dans le calcul de l’addition
  2. Bcounter++ se décompose en lecture, addition et écriture ; si les traitements des deux threads se chevauchent, l’addition de l’un est perdue
  3. CLe nombre d’itérations est automatiquement divisé par deux pour chaque thread
Afficher la réponse et l'explication

Réponse : B. counter++ se décompose en lecture, addition et écriture ; si les traitements des deux threads se chevauchent, l’addition de l’un est perdue

counter++ comporte trois opérations : lire la valeur en mémoire, ajouter 1 et réécrire en mémoire. Si le thread A lit 100 et que, avant sa réécriture, le thread B lit aussi 100, les deux écrivent 101 et deux additions n’en valent qu’une. C’est un exemple typique de course aux données. En utilisant une instruction d’addition atomique, ou un verrou garantissant qu’un seul thread met à jour à la fois, on obtient correctement 200000.

S'entraîner sur ce thème Retour au thème

Autres questions sur Multicœur et synchronisation

  1. Quelle description d’une instruction atomique (instruction indivisible) est correcte ?
  2. Quel est le fonctionnement de l’instruction atomique CAS (compare-and-swap) ?
  3. Le code ci-dessus double la variable partagée counter au moyen de CAS(&p, valeur attendue, nouvelle valeur). Dans quel cas le CAS échoue-t-il et la boucle recommence-t-elle ?
  4. Avec une paire d’instructions comme LR/SC (load-reserved/store-conditional) de RISC-V, dans quel cas le SC (store-conditional) échoue-t-il ?
  5. Quelle description du problème ABA, qui affecte les structures de données sans verrou utilisant CAS, est correcte ?

Comparatifs sur ce thème