IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Threads & Processus C++ Discussion :

Le mot-clé volatile


Sujet :

Threads & Processus C++

  1. #1
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Par défaut Le mot-clé volatile
    Bonjour à tous

    Je viens de tomber sur cet article de A.Alexandrescu datant de février 2001, et j'en viens à m'interroger sur cette approche qui consiste à qualifier en volatile non pas les types primitifs, mais les objets thread-safe eux-même et leurs méthodes.

    J'aimerais avoir votre avis là dessus.

    Est-ce toujours d'actualité ?
    Vis à vis de Boost.Thread, cette approche est-elle complémentaire, superflue, proscrite, ... ?

  2. #2
    screetch
    Invité(e)
    Par défaut
    volatile n'est pas suffisant et est souvent faux, pour faire du vrai thread safe il faut utiliser des memory barriers et des opérations thread-safe comme des operations interlocked et des mutex (qui ont le bon gout d'être aussi des memory barriers)

    une memory barrier et/ou une instruction interlocked instruit au compilateur que la memoire peut avoir changé et donc va desactiver certaines optimisations autour de cette instruction - mais pas partout comme le volatile le fait.

    le volatile est prévu pour quelque chose d'autre, a ne pas utiliser.

  3. #3
    Membre émérite
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Par défaut
    Citation Envoyé par screetch Voir le message
    [...]
    le volatile est prévu pour quelque chose d'autre, a ne pas utiliser.
    Et qu'est-ce que ce "quelque chose d'autre" ?

    Au passage, si le mutex est géré dans une librairie annexe, comment le compilateur peut-il savoir qu'il ne faut pas optimiser autour de cet appel à une librairie externe ?

  4. #4
    screetch
    Invité(e)
    Par défaut
    justement parce que tu ne sais pas quel etat peut etre modifié par une biblitheque annexe. quand tu appeles printf, tes variables globales sont rechargées car le compilateur ne sait pas ce qui peut avoir changé a l'interieur de printf.
    et volatile etait utilisé pour les variables qui pouvaient changer de valeur sans intervention du programme; une valeur mappée en mémoire que le hardware pouvait mettre a jour.

  5. #5
    Membre émérite
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Par défaut
    Mais si ce n'est pas une variable globale, mais que les deux threads possèdent tous deux un pointeur vers un objet déclaré sur le tas, est-ce que cette variable sera également rechargée à la suite d'un appel à une librairie externe ?
    Et si c'est un pointeur vers un objet déclaré sur le tas ?
    Si les réponses sont oui, alors tout appel à une librairie externe oblige à recharger toute la mémoire. Ce qui est quand même peu performant.
    Si les réponses sont non, alors volatile a encore une utilité en dehors de la modification par le hardware.

  6. #6
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Par défaut
    J'ai l'impression que vous n'avez pas lu l'article jusqu'au bout.
    A.A. ne propose pas de sécuriser des données avec volatile. Il utilise déjà des mutex et des équivalents de boost::scoped_lock dans ses exemples pour prévenir les accès concurrents à ses données. Ce qui m'interroge, c'est cette manière qu'il a d'utiliser le qualifier volatile qui me semble presque détournée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    /* Let's illustrate how volatile works on user-defined types on an example. */
     
    class Gadget
    {
    public:
        void Foo() volatile;
        void Bar();
        ...
    private:
        String name_;
        int state_;
    };
    ...
    Gadget regularGadget;
    volatile Gadget volatileGadget;
     
    /* If you think volatile is not that useful with objects, prepare for some surprise. */
     
    volatileGadget.Foo(); // ok, volatile fun called for volatile object
     
     
    regularGadget.Foo();  // ok, volatile fun called for non-volatile object
    volatileGadget.Bar(); // error! Non-volatile function called for volatile object!


    D'ailleurs, à propos de l'utilisation "classique" de volatile, il précise même :
    Don't use volatile directly with primitive types.

  7. #7
    screetch
    Invité(e)
    Par défaut
    l'utilité de volatile n'est pas de corriger les problèmes de threads, vraiment. j'ai fait une bibliothèque de multithread avec un peu de mutex, beaucoup d'interlocked et pas de volatile, et je n'ai pas eu de problème.
    mais les variables partagées doivent utiliser des *vrais* moyens, portables, de partage entre threads (ce que volatile n'est pas, ou est seulement indirectement)

  8. #8
    screetch
    Invité(e)
    Par défaut
    Citation Envoyé par cob59 Voir le message
    J'ai l'impression que vous n'avez pas lu l'article jusqu'au bout.
    A.A. ne propose pas de sécuriser des données avec volatile. Il utilise déjà des mutex et des équivalents de boost::scoped_lock dans ses exemples pour prévenir les accès concurrents à ses données. Ce qui m'interroge, c'est cette manière qu'il a d'utiliser le qualifier volatile qui me semble presque détournée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    /* Let's illustrate how volatile works on user-defined types on an example. */
     
    class Gadget
    {
    public:
        void Foo() volatile;
        void Bar();
        ...
    private:
        String name_;
        int state_;
    };
    ...
    Gadget regularGadget;
    volatile Gadget volatileGadget;
     
    /* If you think volatile is not that useful with objects, prepare for some surprise. */
     
    volatileGadget.Foo(); // ok, volatile fun called for volatile object
     
     
    regularGadget.Foo();  // ok, volatile fun called for non-volatile object
    volatileGadget.Bar(); // error! Non-volatile function called for volatile object!


    D'ailleurs, à propos de l'utilisation "classique" de volatile, il précise même :
    j'ai lu le debut et il dit bien que le mot clé volatile permet de faire du partage de donnée entre threads. ce qu'il faut un peu après est très alexandresque avec un peu de metaprogramming pour faire du code un peu joli, mais dans l'ensemble il ne faudrait pas utiliser volatile.
    franchement, en 10 ans, alexandrescu s'est bien amélioré, ce qu'il disait la etait certes en avance sur l'époque mais un peu en retard par rapport a maintenant, c'est devenu faux ou obsolete.

  9. #9
    screetch
    Invité(e)
    Par défaut
    et comme c'est pas facile de critiquer alexandrescu sur ce forum, voila quelques liens a lire:
    http://software.intel.com/en-us/blog...d-programming/
    http://stackoverflow.com/questions/4...ulti-threading
    http://drdobbs.com/parallel/212701484
    voila j'espere qu'avec l'aide de herb sutter j'arriverai a convaincre ceux qui sont encore un peu incrédules.

    (j'ai moi même été convaincu par quelqu'un sur ce forum il y a deux ans)

  10. #10
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    @screetch: Alexandrescu est aussi au courant du problème de volatile depuis quelques années déjà : http://www.aristeia.com/Papers/DDJ_J...04_revised.pdf . Sauf que ce qui rendait le comportement non spécifique c'est que le standard n'intégrait aucune notion de MT, donc volatile protégait bien des réordonnances d'opérations, mais que pour un seul thread. Sauf que maintenant le standard prend en compte le MT et que les paragraphes qui définissaient le comportement associé à volatile sont quasi-identique, cette utilisation de volatile devient légitime. Cependant il faut aussi noté que le standard propose aujourd'hui des éléments qui doivent permettre de se passer de ceci dans bien des cas (opérations atomiques).

  11. #11
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    C'est pas l'article où il suggère d'utiliser volatile pour son effet sur le système de type (pour empécher statiquement l'appels de membres dont l'appelant doit avoir acquis un mutex) plus que pour sa sémantique dans le language? Si j'ai bonne mémoire cet article propageait une mauvaise notion de la sémantique dans le language (il l'admet d'ailleurs depuis longtemps), mais l'utilisation dans pour son effet sur le système de type était saine bien que non conventionnelle. Comme elle n'a pas pris, elle resterait non conventionnelle et donc plutôt à éviter si on ne fait pas de l'expérimentation.

  12. #12
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Flob90 Voir le message
    Sauf que maintenant le standard prend en compte le MT et que les paragraphes qui définissaient le comportement associé à volatile sont quasi-identique, cette utilisation de volatile devient légitime.
    Non.
    Cependant il faut aussi noté que le standard propose aujourd'hui des éléments qui doivent permettre de se passer de ceci dans bien des cas (opérations atomiques).
    Les papiers qui définissent le modèle de mémoire ont envisagé et rejetté la possibilité de donner à volatile un sens en MT. Et les problèmes de modèles de mémoire vont au delà des opérations atomiques (qui à la base ne s'occupent que de ce qui se passe pour une variable, pas de la synchronisation des opérations qui en impliquent plusieurs, même si elles sont toutes atomiques; l'interface de C++11 a des effets sur les deux aspects), une des raisons pour lesquelles toucher à volatile n'était pas adéquat.

  13. #13
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    @Jean-Marc.Bourguet:Non à : "Sauf que maintenant le standard prend en compte le MT" ?

    Parce que le reste j'ai vérifié avant de poster quand même, section 1.9 paragraphes 12 et 14 (n3424). Mais si ils ne sont toujours pas valide si il y a plusieurs threads ils ne valent rien. (A moins qu'il y ait des contre-indications dans le 1.10 ?)

    J'ai du mal à comprendre comment le standard peut intégrer des éléments de MT sans définir le modèle mémoire qui va avec.

  14. #14
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    C'est pas l'article où il suggère d'utiliser volatile pour son effet sur le système de type (pour empécher statiquement l'appels de membres dont l'appelant doit avoir acquis un mutex) plus que pour sa sémantique dans le language? Si j'ai bonne mémoire cet article propageait une mauvaise notion de la sémantique dans le language (il l'admet d'ailleurs depuis longtemps), mais l'utilisation dans pour son effet sur le système de type était saine bien que non conventionnelle. Comme elle n'a pas pris, elle resterait non conventionnelle et donc plutôt à éviter si on ne fait pas de l'expérimentation.
    Ah, merci, enfin quelqu'un qui a compris de quoi parlait cet article.
    J'ai aussi eu l'impression que la sémantique de volatile était faussée dans ce type d'usage, bien qu'il permette de diagnostiquer statiquement certaines erreurs. Sur sur cet aspect-là que j'aurais aimé avoir vos avis, pas sur l'opportunité d'une utilisation "classique" de volatile.

  15. #15
    screetch
    Invité(e)
    Par défaut
    le but de mettre volatile sur l'objet au lieu de sur la variable, est que alors tout l'objet devient volatile; chaque variable membre devient volatile. Le volatile est donc "propagé" jusqu'aux variables membres et ainsi le code peut s'executer en thread safe (d'après lui)

    c'est cette partie la que je critique

    ce que j'aimerai en C++ c'est pouvoir ajouter des attributs qui deviendraient comme "volatile" et "const" des modificateurs. Sans autre particularité que de restreindre l'accès a un objet aux méthodes ayant cet attribut; par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    attribute shared; // shared en soit ne veut rien dire, ca pourrait être xyz
     
    class PartiallyThreadSafe
    {
    public:
      int doStuff() shared;
      int nonThreadSafe();
    };
     
     
    shared PartiallyThreadSafe myValue;
    voila, et j'ai deja pensé utiliser volatile dans ce sens.
    malheureusement volatile a des effets très ennuyeux sur la lecture de variable.
    Le but d'alexandrescu est bien d'utiliser cet effet de volatile au final, mais DE PLUS de donner des methodes qui permettent l'accès a des données volatiles. c'est cette partie la qui est fausse.

  16. #16
    Membre émérite
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Par défaut
    Citation Envoyé par screetch Voir le message
    [...]
    mais les variables partagées doivent utiliser des *vrais* moyens, portables, de partage entre threads (ce que volatile n'est pas, ou est seulement indirectement)
    volatile n'a jamais prétendu être un moyen de partage à lui seul. C'est un outil pour éviter d'autres problèmes.
    Par ailleurs, tu ne sembles pas avoir répondu à mes remarques sur les pointeurs ... ?

    Citation Envoyé par screetch Voir le message
    j'ai lu le debut et il dit bien que le mot clé volatile permet de faire du partage de donnée entre threads. ce qu'il faut un peu après est très alexandresque avec un peu de metaprogramming pour faire du code un peu joli, mais dans l'ensemble il ne faudrait pas utiliser volatile.
    Il dit simplement que volatile permet de "synchroniser" la mémoire, dans le sens où une écriture dans une variable volatile sera écrite immédiatement en mémoire, et non reportée à plus tard en la gardant en registre.
    L'exemple basic qu'il donne étant celui de la boucle while.
    Jamais il ne dit qu'il ne faudrait pas utiliser volatile. Il dit simplement que volatile est moins utile pour les types intégrés que pour les types déclarés par l'utilisateur.

    Citation Envoyé par screetch Voir le message
    franchement, en 10 ans, alexandrescu s'est bien amélioré, ce qu'il disait la etait certes en avance sur l'époque mais un peu en retard par rapport a maintenant, c'est devenu faux ou obsolete.
    En quoi est-ce devenu faux ou obsolète ? Avec les compilateurs qui optimisent de plus en plus, ce qu'il affirme me semble au contraire prendre de plus en plus d'importance.

    Citation Envoyé par screetch Voir le message
    et comme c'est pas facile de critiquer alexandrescu sur ce forum, voila quelques liens a lire:
    http://software.intel.com/en-us/blog...d-programming/
    http://stackoverflow.com/questions/4...ulti-threading
    http://drdobbs.com/parallel/212701484
    voila j'espere qu'avec l'aide de herb sutter j'arriverai a convaincre ceux qui sont encore un peu incrédules.

    (j'ai moi même été convaincu par quelqu'un sur ce forum il y a deux ans)
    Je n'ai aucune "admiration" pour alexandrescu. A vrai dire, je n'avais même pas cherché l'auteur de l'article.
    Ce qui m'a semblé important, ce sont les arguments avancés dans l'article.
    Par ailleurs, je vais lire les liens, et si ils me font changer d'avis je reviendrai éditer.

    Edit : Me revoilà :
    http://software.intel.com/en-us/blog...d-programming/
    Sauf qu'ils ne parlent pas de la même chose. Ici, Arch Robison parle de volatile pour des types intégrés au langage (zut, j'ai oublié le nom ... les int & co. , quoi)
    Alors que de l'autre côté, c'est des structures que alexandrescu parle. Au passage, il dit même que le volatile sur les int&co est beaucoup moins utile, et que celui-ci est déconseillé par lui.

    http://stackoverflow.com/questions/4...ulti-threading
    Déjà, je remarque que la réponse la plus up-votée renvoie vers un lien vers l'article d'alexandrescu. Hasard ou non ?
    Et pour les reste des réponses, elles ne parlent que des int&co.

    http://drdobbs.com/parallel/212701484
    Même remarque : Ici, on parle encore des int&co.





    Alors que, si j'ai bien compris, alexandrescu propose de marquer volatile toutes les méthodes qui sont thread-safe en elles-mêmes, et d'utiliser les volatile sur des objets de class / struct. Puis d'utiliser un LockingPtr pour permettre l'accès aux méthodes non volatile.

  17. #17
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Flob90 Voir le message
    @Jean-Marc.Bourguet:Non à : "Sauf que maintenant le standard prend en compte le MT" ?
    Non à "cette utilisation de volatile devient légitime."

    Parce que le reste j'ai vérifié avant de poster quand même, section 1.9 paragraphes 12 et 14 (n3424). Mais si ils ne sont toujours pas valide si il y a plusieurs threads ils ne valent rien. (A moins qu'il y ait des contre-indications dans le 1.10 ?)

    J'ai du mal à comprendre comment le standard peut intégrer des éléments de MT sans définir le modèle mémoire qui va avec.
    1.10 définit le modèle de mémoire. 1.10 ne dit rien de l'effet de volatile sur le modèle mémoire (la seule mention est quand il autorise les optimisations qui n'ont pas d'effet observable, et l'accès à volatile est donné comme un des effets observables potentiels -- ce qui est en ligne avec le rest). volatile n'est donc pas un moyen de s'assurer de synchronisation entre threads.

  18. #18
    screetch
    Invité(e)
    Par défaut
    volatile force aussi a recharger de la mémoire a chaque accès.
    l'ecriture en mémoire se produit en général au bon moment, la premiere lecture se produit aussi au bon moment, ce sont les relectures qui ne se produisent pas au bon moment.

    au niveau des pointeurs, je ne suis pas un compilateur; le problème est le même en monothread et en multithread, il faut detecter au mieux ce qui n'a pas pu être changé (les variables locales, en considerant qu'on a pas de pointeur qui peut pointer dessus)
    a partir du moment ou tu as un pointeur tu ne sais pas sur quoi il pointe, que ce soit le tas ou la pile, du coup tu recharges.

    voila par exemple le résultat du code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <cstdio>
     
    int main()
    {
        int x = 2, *y = &x;
        printf("%p\n", y);
        printf("%d\n", x);
        printf("%p\n", y);
        printf("%d\n", x);
        return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    0x0000000100000ec0 <main+0>:	push   %rbp
    0x0000000100000ec1 <main+1>:	mov    %rsp,%rbp
    0x0000000100000ec4 <main+4>:	push   %r15
    0x0000000100000ec6 <main+6>:	push   %r14
    0x0000000100000ec8 <main+8>:	push   %rbx
    0x0000000100000ec9 <main+9>:	sub    $0x8,%rsp
    0x0000000100000ecd <main+13>:	movl   $0x2,-0x1c(%rbp)
    0x0000000100000ed4 <main+20>:	lea    0x7d(%rip),%rbx        # 0x100000f58
    0x0000000100000edb <main+27>:	lea    -0x1c(%rbp),%r14
    0x0000000100000edf <main+31>:	mov    %rbx,%rdi
    0x0000000100000ee2 <main+34>:	mov    %r14,%rsi
    0x0000000100000ee5 <main+37>:	xor    %al,%al
    0x0000000100000ee7 <main+39>:	callq  0x100000f2e <dyld_stub_printf>
    0x0000000100000eec <main+44>:	mov    -0x1c(%rbp),%esi
    0x0000000100000eef <main+47>:	lea    0x66(%rip),%r15        # 0x100000f5c
    0x0000000100000ef6 <main+54>:	mov    %r15,%rdi
    0x0000000100000ef9 <main+57>:	xor    %al,%al
    0x0000000100000efb <main+59>:	callq  0x100000f2e <dyld_stub_printf>
    0x0000000100000f00 <main+64>:	mov    %rbx,%rdi
    0x0000000100000f03 <main+67>:	mov    %r14,%rsi
    0x0000000100000f06 <main+70>:	xor    %al,%al
    0x0000000100000f08 <main+72>:	callq  0x100000f2e <dyld_stub_printf>
    0x0000000100000f0d <main+77>:	mov    -0x1c(%rbp),%esi
    0x0000000100000f10 <main+80>:	mov    %r15,%rdi
    0x0000000100000f13 <main+83>:	xor    %al,%al
    0x0000000100000f15 <main+85>:	callq  0x100000f2e <dyld_stub_printf>
    0x0000000100000f1a <main+90>:	xor    %eax,%eax
    0x0000000100000f1c <main+92>:	add    $0x8,%rsp
    0x0000000100000f20 <main+96>:	pop    %rbx
    0x0000000100000f21 <main+97>:	pop    %r14
    0x0000000100000f23 <main+99>:	pop    %r15
    0x0000000100000f25 <main+101>:	pop    %rbp
    0x0000000100000f26 <main+102>:	retq
    en gras, tu peux voir que après avoir stocké une variable, le compilo a quand même rechargé deux fois la variable locale a cause de son alias. On ne sait pas apres printf ce qui a été changé.

    met toi a la place du compilo, comment peux tu être sur que la valeur n'a pas été changée? les compilos sont très protectionnistes sur ces cas.
    rappelle toi aussi que this est un pointeur et on ne sait pas si un objet est sur le tas ou la pile, en général. du coup toutes les données membres peuvent changer en permanence.

    volatile est donc redondant dans ce cas.
    volatile ne sert qu'a cacher des bugs ou on ecrit un peu comme une porcasse dans une variable de manière non thread safe et on espère qu'elle sera bien changée dans l'autre thread de manière correcte.

  19. #19
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    @Jean-Marc.Bourguet: J'avais pas lu le paragraphe 13 du 1.9 qui dit bien que la notion de sequenced before n'est valable que pour un thread. J'en ai profité pour lire le 1.10 en même temps.

    Pourquoi le comité n'a pas choisie de donner à volatile un sens en MT comme en Java1.5/C# (si j'en crois le point 10 de l'article http://www.aristeia.com/Papers/DDJ_J...04_revised.pdf) ?

  20. #20
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut Mini tutoriel
    * volatile. Les accès à ces variables sont des effets de bords visibles, donc tous doivent se retrouver répercutés et aucun ne doit être ajouté. Conçu pour les IO mappées en mémoire (ce qui suppose de nos jours un contrôle supplémentaires pour indiquer que ces zones mémoires ne sont pas cachable -- ce qui les compilateurs ne font pas parce que ce n'est pas eux qui gèrent ces attributs).

    * atomique. Tout ou rien. L'extérieur ne peut pas voir une modification partielle.

    * cohérence de cache. Le mécanisme qui fait qu'une écriture à un endroit donné va se retrouver finalement visible par les autres processeurs. Il y a eu des processeurs où il fallait faire des actions explicites, mais de nos jours c'est passé de mode, une écriture déclanche automatiquement les actions nécessaires.

    * modèle de consitance de mémoire. Quelles sont les garanties de visibilité quand plusieurs emplacement mémoire sont en cause? (Note: la granularité d'un emplacement, ce n'est pas le byte, c'est plutôt le plus grand objet atomique possible.) Les modèles utilisés en pratique par les processeurs par exemple ne garantissent pas que si une thread 1 fait deux écritures (dans A puis dans B), une thread 2 ne puisse pas voir la nouvelle valeur de B mais l'ancienne valeur de A (pendant un temps: la cohérence de cache assure que la nouvelle valeur de A sera finalement visible, simplement elle ne garantit pas que celle de B ne sera pas visible avant). Il y a des instructions, les "barrières mémoire" qui permettent d'ajouter des garanties avec des degrés de rafinement divers (la plupart des processeurs n'ont besoin dans mon exemple que d'une barrière entre les deux écritures, l'Alpha a aussi besoin d'une barrière entre les deux lectures)

    Donc des barrières mémoire sont nécessaires pour la synchronisation des threads. Mais elles ne le sont généralement pas pour les IO en mémoire (et quand elles le sont, ce ne sont pas nécessairement les mêmes). Et dans l'autre sens, une correspondance fine entre les accès au niveau du langage et ceux générés est nécessaire pour volatile, mais pas pour la synchronization entre threads (a=1; a=0; on doit faire les 2 pour les IO, s'il n'y a pas de barrière entre les deux, c'est pas nécessaires pour les threads).

    volatile ne fait donc pas tout ce qu'il faut pour les threads d'une part tout en empéchant des optimisations qui sont possibles pour les threads.

Discussions similaires

  1. demande de précision sur le mot-clef volatile
    Par archimondain dans le forum Threads & Processus
    Réponses: 13
    Dernier message: 01/03/2012, 19h27
  2. mot clef volatile précision
    Par guillaume07 dans le forum C++
    Réponses: 26
    Dernier message: 18/12/2010, 09h09
  3. mot clef volatile
    Par elmcherqui dans le forum C++
    Réponses: 4
    Dernier message: 11/04/2008, 21h25
  4. Mot clé volatile
    Par Invité dans le forum C
    Réponses: 6
    Dernier message: 27/10/2006, 11h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo