2010-06-06 5 views
1

Contextela cohérence du cache et d'un thread

J'ai lu dans divers livres et articles pour en savoir plus sur les caches du processeur, la cohérence du cache, et les barrières de mémoire dans le cadre de l'exécution simultanée. Jusqu'à présent, cependant, j'ai été incapable de déterminer si une pratique de codage commune de la mienne est sûre au sens le plus strict.

Hypothèses

  1. Le pseudo-code suivant est exécuté sur une machine à deux processeurs:

    int sharedVar = 0; 
    
    myThread() 
    { 
        print(sharedVar); 
    } 
    
    main() 
    { 
        sharedVar = 1; 
        spawnThread(myThread); 
        sleep(-1); 
    } 
    
  2. main() exécute le processeur 1 (P1), tandis que MyThread () s'exécute sur P2.

  3. Dans un premier temps, sharedVar existe dans les caches des deux P1 et P2 avec la valeur initiale de 0 (en raison d'un "code d'échauffement" qui ne figure pas ci-dessus.)

Question

Strictement parlant - de préférence sans supposer un type particulier de CPU - myThread() est-il garanti d'imprimer 1? Avec ma nouvelle connaissance des caches de processeurs, il semble tout à fait possible qu'au moment de l'instruction print(), P2 n'ait pas reçu la demande d'invalidation de sharedVar causée par l'affectation de P1 dans main(). Par conséquent, il semble possible que MyThread() pourrait imprimer 0.

Références

Ce sont les articles connexes et des livres que j'ai lu:

  1. Shared Memory Consistency Models: A Tutorial
  2. Memory Barriers: a Hardware View for Software Hackers
  3. Linux Kernel Memory Barriers
  4. Computer Architecture: A Quantitative Approach

Répondre

1

Strictement parlant - de préférence sans supposer un type particulier de CPU - myThread() est-il garanti d'imprimer 1?

Théoriquement, il peut imprimer soit 0 ou 1, même sur x86, depuis stores can move after loads on almost any architecture. En pratique, il serait difficile de faire myThread() imprimer 0.
La création d'un thread fonctionnera vraisemblablement comme un stockage/une distribution implicite memory barrier car il aurait probablement:
- avoir au moins une instruction le long du chemin d'exécution qui entraîne une barrière de mémoire - instructions interverrouillées, instructions de barrière de mémoire explicite, etc. .,
- ou le magasin serait simplement retiré/drainé du store buffer au moment où myThread() est appelé, puisque la création d'un nouveau thread entraîne l'exécution de nombreuses instructions - parmi lesquelles de nombreux magasins.

0

Je parle que Java ici: myThread() est garanti d'imprimer 1, en raison de la happens before definition du La spécification du langage Java (section 17.4.5).

L'écriture à sharedVar dans main()se produit avant fraie le fil avec fonction myThread(), car l'affectation variable est d'abord dans l'ordre du programme. Ensuite, engendrer un thread se produit avant toutes les actions dans le thread en cours de démarrage. Par la transitivité de la définition à la section 17.4.5 (hb (x, y) et hb (y, z) implique hb (x, z)), l'écriture à la variable sharedVarpasse avantprint() lit sharedVar en myThread().

Vous pourriez également apprécier l'article de Brian Goetz Java theory and practice: Fixing the Java Memory Model, Part 2 couvrant ce sujet, aussi bien que son livre Java Concurrency in Practice.

Questions connexes