Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 01/11/2011, à 02:55

ehmicky

[C++]volatile méthodes

Bonjour à tous,

Je découvre l'existence de méthodes volatile. Par exemple :

class A
{
   void fonc(void) volatile {};
};

Permet à une instantiation volatile de A d'utiliser fonc(), sans pour autant empêcher les instantiations non-volatiles de le faire (un peu comme const).
Ma première question est : pourquoi quiconque aurait envie de déclarer une classe volatile ? Il me semble que les seuls intérêts de volatile sont dans des situations utilisant des types builtins (sauf pour les variables volatile entre un setjmp et un longjmp, mais bon les goto... smile )

Ensuite, en recherchant des infos sur cette question, je suis tombé sur ce post de kernel.org, "Volatile considered harmful", qui déconseille l'utilisation de volatile même dans le noyau. Ma deuxième question serait donc : existe-t-il cependant des cas où volatile est une bonne chose ? Je pense notamment à une opération atomique qui doit utiliser des sig_atomic_t (plus grand type pouvant être accédé en une instruction CPU) volatile pour éviter que le compilateur ne transtype sig_atomic_t.

Merci beaucoup smile

Dernière modification par ehmicky (Le 01/11/2011, à 02:56)


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#2 Le 01/11/2011, à 09:29

grim7reaper

Re : [C++]volatile méthodes

Salut,

ehmicky a écrit :

ce post de kernel.org, "Volatile considered harmful", qui déconseille l'utilisation de volatile même dans le noyau.

Bon article, mais pour le C (le noyau est codé en C, pas en C++ et comme tu le sais ce sont des langages bien distinct).

ehmicky a écrit :

Ma deuxième question serait donc : existe-t-il cependant des cas où volatile est une bonne chose ?

Oui, et c’est Andrei Alexandrescu qui le dit (donc une pointure en C++). Je ne sais pas si tu le connais, mais c’est le père de Loki (dont Boost à repris beaucoup de concept) et l’auteur de Modern C++ Design.

De manière générale, si tu ne connais pas jjà, e te conseille de lire ce site et celui (regarde un peu l’Advisory Board :]).
Niveau C++ il a de très bon articles, d’un niveau technique assez avancé et rédigé par des monstres du C++ (Bjarne Stroustrup, Andrew Koenig, Herb Sutter, Scott Meyers, Andrei Alexandrescu, Jim Coplien, …).

Hors ligne

#3 Le 01/11/2011, à 16:03

ehmicky

Re : [C++]volatile méthodes

Salut,

Merci beaucoup pour ta question. Article très intéressant smile. Donc si j'ai bien saisi :
  - toute variable pouvant être partagée par plusieurs threads doit être volatile
  - ainsi une classe pouvant (ou non) être partagée par plusieurs threads doit faire un "volatile overload" de ses méthodes (suivant que la classe a été déclarée volatile ou non, les méthodes présupposent qu'elle est utilisée dans un contexte multithreaded, et que des procédés de sychronisation sont nécessaires).
Je suis dubitatif sur le deuxième point cependant : cela n'exige-t-il pas de faire porter la charge de la thread-safety sur le client ? En effet, la thread-safety dépend du fait que le client de l'interface déclare la classe volatile ou non, et personnellement, j'ai pris l'habitude de ne jamais faire confiance au client surtout pour des choses critiques comme cela. Qu'en penses-tu ?


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#4 Le 01/11/2011, à 16:41

grim7reaper

Re : [C++]volatile méthodes

Bah c’est un moyen de se faire aider par le compilo et de proposer un service aux utilisateurs, mais c’est sûr que ça ne fait pas tout.
Cette méthode aide à mettre en place et renforcer la thread safety, mais ça ne la met pas en œuvre à elle seule.
Mais dans tous les cas, tu y gagnes à la faire.
Si tu ne le fais pas :
- utilisateurs « mal élevé » (n’utilise pas volatile) => bah pas de bonus thread safety ;
- utilisateurs « bien élevé » (utilise volatile => bah pas de bonus thread safety.

Si tu le fais :
- utilisateurs « mal-élevé » (n’utilise pas volatile) => bah pas de bonus thread safety ;
- utilisateurs « bien élevé » (utilise volatile => bonus thread safety avec tes surcharges.

Donc autant récompenser les gens qui codent bien. Ça ne change rien pour les autres.
Du moins, c’est comme ça que je le vois.

Hors ligne

#5 Le 01/11/2011, à 16:57

ehmicky

Re : [C++]volatile méthodes

En fait je pensais à comme alternative :

1) ne pas définir de volatile overload, et mettre des procédés de synchronisation que la classe soit volatile ou non.
Comme ça, utilisateur mal élevé a toujours une classe thread-safe, au détriment de l'utilisateur bien élevé, et qui utilise la classe dans un contexte "non-multithreaded", et qui devra donc enclencher des procédés de synchronization inutiles.

2) forcer l'utilisateur à faire le choix entre volatile ou non, via des typedefs aux noms explicites :

struct Classe
{
    void Methode( void )
    { std::cout << "Méthode dans un contexte non-multithreaded\n"; }        
    void Methode( void ) volatile
    { std::cout << "Méthode dans un contexte multithreaded\n"; }        
};
typedef Classe ClasseUnsafe;
typedef volatile Classe ClasseSafe;

(Classe devant ensuite être dissimulée de l'interface)

3) Utiliser une macro pour décider que toutes les instances de cette classe (et des autres) soient thread-safe ou non, avec comme choix par défaut (absence de #define) la thread-safety :

#define    NON_MULTITHREADED

struct Classe
{
    void Methode( void )
    { std::cout << "Méthode dans un contexte non-multithreaded\n"; }        
    void Methode( void ) volatile
    { std::cout << "Méthode dans un contexte multithreaded\n"; }        
};
#ifdef NON_MULTITHREADED
typedef Classe ClasseUser;
#else
typedef volatile Classe ClasseUser;
#endif

Dernière modification par ehmicky (Le 01/11/2011, à 17:23)


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#6 Le 01/11/2011, à 17:21

grim7reaper

Re : [C++]volatile méthodes

Moi ça me ferait mal de pénaliser (perte de perf’ non justifié) ceux qui codent bien et lisent la doc’. Ça me ferait mal en tant que concepteur, et ça me ferait chier en tant qu’utilisateur.
Si un gugus lit pas la doc d’une bibliothèque (ou ne sais pas utiliser volatile) c’est de sa faute et s’il a des emmerdes, il assume (il n’avait qu’a lire la doc avant de coder).

Je comprends que tu veuilles protéger l’utilisateur contre lui-même, mais je pense que c’est un combat vain et ça t’impose des contraintes supplémentaires.

Après, c’est toi qui vois.

Hors ligne

#7 Le 01/11/2011, à 17:29

ehmicky

Re : [C++]volatile méthodes

Edit du post précédent :
La solution 2 et 3 permettraient d'avoir à la fois l'efficience pour l'utilisateur prudent, et la sûreté pour l'utilisateur négligent, au détriment d'une complexification de l'interface. Qu'en penses-tu ?


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#8 Le 01/11/2011, à 17:35

grim7reaper

Re : [C++]volatile méthodes

Entre les 3, je préfère là 2.
La 1, tu sais ce que j’en pense.
La 3 induit une perte de souplesse : soit toutes les instances sont thread safe, soit aucune ne l’est.
La 2 permet de ne pas pénaliser les « bons » utilisateurs et conserve la souplesse de la technique présenté dans l’article.

Cela dit, la 2 ne fait que déplacer le problème : au lieu de penser à mettre volatile il faut penser à instancier une ClasseSafe au lieu d’une ClasseUnsafe…
C’est peut-être plus explicite, mais ça ne change pas le problème.

Dernière modification par grim7reaper (Le 01/11/2011, à 17:37)

Hors ligne

#9 Le 01/11/2011, à 18:04

ehmicky

Re : [C++]volatile méthodes

Pour la 2, cela change aussi le fait que la classe n'est plus "par défaut" thread-unsafe (demandant à l'utilisateur une action pour la rendre thread-safe), mais peut être l'inverse si je fais :

class ClasseUserUnsafe { ... };
typedef volatile ClasseUserUnsafe ClasseUser;

et que je documente principalement ClasseUser, avec un dernier paragraphe précisant l'existence de ClasseUserUnsafe pour ceux ne désirant pas les pertes de performance dûs aux procédés de synchronisation, cela met en avant la classe thread-safe, qui sera utilisée par la majorité des utilisateurs, en réservant la classe unsafe pour les quelques utilisateurs ayant bien lu la doc tongue
Mais encore une fois, ça multiplie le nombre de classes, là où un volatile suffit comme tu le dis.

Le truc, c'est que j'aimerais être prudent avec les problèmes de synchronisation, parce que ce sont des bugs difficiles à tracker, qui surviennent pas à chaque exécution, mais le jour où ils surviennent, mes utilisateurs sauront pas où chercher.


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#10 Le 02/11/2011, à 11:16

Luc Hermitte

Re : [C++]volatile méthodes

Je reviens sur 2-3 trucs.
Non en MT, il ne faut pas déclarer des variables volatiles. De base, cela n'apporte strictement rien d'utile (relativement au MT) (en dehors des derniers VC++). Je vous renvoie à d'autres discussions qui invalident la première partie de l'article.
- http://software.intel.com/en-us/blogs/2 … ogramming/
- http://www.alexonlinux.com/multithreade … -variables

L'article d'Andrei Alexandrescu démontre une utilisation détournée de volatile qui s'inspire de la const-correctness. const est un tag qui marque la non-mutabilité sémantique. AA, dans son article, propose la même chose avec volatile pour marquer les zones protégées contre les accès concurrents -- OK, cela va revenir à marquer quelques variables.
Tout surcharger ? Hum... Ce n'est probablement pas la bonne chose à faire. Ce n'est définitivement pas ce que l'on fait avec const. Quand on conçoit, on essaie de savoir ce que cela vaut pour le MT.

Dans un sujet très proche, Scott Meyers avait tenté une petite expérience pour faire de la preuve (en gros). C'est à dire pour tagguer les fonctions quant aux propriétés/garanties qu'elles offrent. Hormis les temps de compilation titanesques (sur une précédente génération de compilos), son expérience avait été concluante. On retrouverait pratiquement les même bonus qu'avec volatile (en cv-qualifier de fonctions membres), mais sans tagguer "volatile" les variables.
-> http://www.artima.com/cppsource/codefeatures.html

Hors ligne