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

Contribuez C++ Discussion :

De la rapidité du code [Trucs & Astuces]


Sujet :

Contribuez C++

  1. #121
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Pour les matrices et vecteurs, voir Blitz++, et dérivés comme boost.uBlas, qui profitent de la méta-progammation pour éliminer les temporaires, obtenir une sémantique de déplacement au niveau des retours, et autres calculs retardés.

    Pré-incrémentation et compagnie n'avaient pas déjà été signalés ?

    Sinon oui, il faut profiter des profileurs de code.

    PS à délester: algorithme "vient" (façon de parler) de l'Arabe (cf Al!) et non du Grec.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  2. #122
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 52
    Points : 55
    Points
    55
    Par défaut
    Ce sujet confirme que je suis tombé sur un site de fous furieux...

  3. #123
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2005
    Messages
    163
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2005
    Messages : 163
    Points : 102
    Points
    102
    Par défaut
    Citation Envoyé par Luc Hermitte
    Pour les matrices et vecteurs, voir Blitz++, et dérivés comme boost.uBlas, qui profitent de la méta-progammation pour éliminer les temporaires, obtenir une sémantique de déplacement au niveau des retours, et autres calculs retardés.

    Pré-incrémentation et compagnie n'avaient pas déjà été signalés ?

    Sinon oui, il faut profiter des profileurs de code.

    PS à délester: algorithme "vient" (façon de parler) de l'Arabe (cf Al!) et non du Grec.
    juste un truc , Al khawarizmi est perse , pas arabe non ?
    http://amokrane-chentir.blogspot.com { Software engineering, .NET technologies, Imagine cup..}

  4. #124
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    Hum j'avais dis ça car je venais de coder une class de vecteur et une class de matrice... Maintenant je vais soit utiliser un type de matrice et de vecteur déjà coder : (D3DXVECTOR3 et D3DXMATRIX) ou bien des insructions 3DNow!
    Première grosse démo en construction :
    http://bitbucket.org/rafy/exo2/

  5. #125
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    La discussion est vieille, mais je voudrais y mettre mon grain de sel.

    Supposons que je veuille optimiser la boucle suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    for (int i=0; i<n; ++i)
      z[i]=x[i]+y[i];
    Beaucoup de propositions précédentes ne sont que superficielles.
    Mais voici les 3 voies principales d'optimisations que je suggère.
    Si vous croyez que les compilos les font automatiquement, vous vous trompez (malheureusement).

    1) instructions parallèles SIMD (SSE1, SSE2 pour les Pentiums)
    Pour les pentium cela permet un gain de:
    -char: 16x
    -short: 8x
    -int, float: 4x
    -double: 2x
    Il faut faire néanmoins attention aux contraintes d'alignement mémoire et éventuellement prévoir de traiter les éléments restants de la boucle.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    float *px=x, py=y, pz=z;
    for (int i=0, imax=n-4; i<imax; px+=4, py+=4, pz+=4, i+=4)
      _mm_store_ps(pz,_mm_add_ps(_mm_load_ps(px),_mm_load_ps(ps)));
    2) développer la boucle
    Certes un Pentium prédit la plupart du temps correctement le saut conditionnel de la boucle 'for', évitant ainsi de briser le pipeline.
    Mais développer la boucle permet un gain important de vitesse, surtout quand les index des tableaux sont constants (instructions plus rapides du Pentium).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    for (int i=0, imax=n-16; i<imax; i+=16)
    {
      float *px=&x[i], py=&y[i], pz=&z[i];
      pz[0]=px[0]+py[0];
      pz[1]=px[1]+py[1];
      ...
    }
    3) Garder autant que possible les variables dans les registres.
    Ainsi si l'on désire calculer Z1=X+Y et Z2=X-Y, pourquoi ne pas faire qu'une seule boucle:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    for (int i=0; i<n; ++i)
    {
      float xi=x[i], yi=y[i];
      z1[i]=xi+yi;
      z2[i]=xi-yi;
    }
    Il n'est pas interdit de mélanger ces 3 techniques.


    Dans un autre ordre d'idées:
    -Le processeur prédit qu'un test 'if' est vérifié. Donc pour minimiser les pipeline brisés (destructeur pour la vitesse), placez le code le moins probable après 'else'.
    -le mot clé 'restrict' peut supprimer l'aliasing. 'restrict' est dans le C99, mais pas encore officiellement dans le C++. Sinon votre compilateur a surement une option de compilation adéquate.

  6. #126
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    tu as écris += 4, je suppose que ça vient de la taille de l'int enfin tu suppose que sizeof(int) vaut toujours 4... Il faut faire gaffe avec ça....
    C'est pas forcement vrai...
    Ce qui est vrai c'est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    sizeof(char) == 1
    et
    sizeof(char) <= sizeof(int) <= sizeof(long)
    de même
    sizeof(float) <= sizeof(double) <= sizeof(long double)
    rien n'empêche que les 3 soient égales
    Première grosse démo en construction :
    http://bitbucket.org/rafy/exo2/

  7. #127
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    tu as écris += 4, je suppose que ça vient de la taille de l'int enfin tu suppose que sizeof(int) vaut toujours 4... Il faut faire gaffe avec ça....
    T'as pas dû comprendre grand chose à mon exemple:
    - J'ai pris des floats pour l'exemple, pas des ints
    - Il y a bien 4 floats dans un registre SSE = 16 octets

  8. #128
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Sa remarque au sujet des constantes magiques reste valide. (Certes dans ton cas, tu vises une archi bien précise, au détriment de la portabilité des perfs.)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  9. #129
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    Il faut éviter le plus possible de semer dans son code des nombres magiques....
    Pour plusieurs raisons :
    -> le coté utilitaire de la chose, dans ton cas si tu veux adapter ça avec un autre type alors tu es obligé de modifier ton code à plusieurs endroits. Tu peux mettre des nombres magiques mais alors fait une ou des variables globals constantes ou alors des variables d'une class static const
    -> le coté parachutage, une valeur qui arrive comme ça d'on ne sait trop ou, j'ai lu dans un bouquin que pour chaque nombre magique qu'on introduit dans son code, il faut au moins une dizaine de lignes pour justifier la valeur et la commenter...
    -> les seuls nombre magiques autorisés (c'est un bien grand mot) sont les nombres qui sont dans une formule.
    exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    const float GetPerimeter(const float Radius)
    {
        return 2 * Pi * Radius;    // En considérant que Pi est une variable globale constante
    }
    Première grosse démo en construction :
    http://bitbucket.org/rafy/exo2/

  10. #130
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    -> le coté utilitaire de la chose, dans ton cas si tu veux adapter ça avec un autre type alors tu es obligé de modifier ton code à plusieurs endroits. Tu peux mettre des nombres magiques mais alors fait une ou des variables globals constantes ou alors des variables d'une class static const
    Mon exemple est en C.
    Mon implémentation réelle des instructions SIMD est faite avec des surcharges, et reste quasi transparente dans mon programme.
    -> le coté parachutage, une valeur qui arrive comme ça d'on ne sait trop ou, j'ai lu dans un bouquin que pour chaque nombre magique qu'on introduit dans son code, il faut au moins une dizaine de lignes pour justifier la valeur et la commenter...
    De quel nombre magique tu parles? 4?
    Renseigne toi sur SSE... C'est toi même qui dit utiliser 3dnow dans un poste précédent! C'est peut-être parce que 3dnow est plus général que SSE?
    -> les seuls nombre magiques autorisés (c'est un bien grand mot) sont les nombres qui sont dans une formule.
    exemple :
    const float GetPerimeter(const float Radius)
    {
    return 2 * Pi * Radius; // En considérant que Pi est une variable globale constante
    }
    Tu veux bien optimiser ce code stp! Tu veux bien me dire en quoi la discussion sur une constante nous intéresse dans une discussion sur l'optimisation.
    Dis moi, tu les as critiqué, tous ceux qui proposent plus haut dans cette discussion de programmer en assembleur?


    Sa remarque au sujet des constantes magiques reste valide. (Certes dans ton cas, tu vises une archi bien précise, au détriment de la portabilité des perfs.)
    Effectivement, j'ai bien dis que dans mon exemple j'utilise SSE, et donc bien entendu je vise l'architecture Intel.
    On ne peut pas sérieusement dire qu'un code est optimisé si on passe à coté des SIMD (quand c'est possible).
    Mais en s'y prenant bien, ce n'est pas pas au détriment de la portabilité du code (surcharge d'opérateurs...c'est ce que j'ai déjà fait).



    Pour tous les as de l'optimisation
    Je vous mets au défit.
    Je propose que l'on teste nos implémentations respectives d'une multiplication de matrices...

  11. #131
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    Pour juger l'optimisation il vaut mieux faire de la gestion de mémoire, faire du travail sur des conteneurs. Un pur calcul entre 2 matrices ne sera pas très parlant !!!
    une personne va mettre 10 ms et l'autre va mettre 11 ms bouh il a fait moins bien que moi.... Il est Null!!!
    C'est naze de dire, et de penser ça...
    L'optimisation doit avant tout porter sur ce qui est de plus lent dans un programme....
    Optimiser un if c'est trop c**
    C'est comme si dans un jeu on optimisait le chargement des niveaux au lieu d'optimiser l'affichage ou le rendu !!!!!
    Le chargement qu'il dure 100 ms de plus car on a un algo qui pourrait être amélioré on s'en fout, par contre si à chaque boucle d'affichage on perd 100ms car l'algo est foireux alors, ça nous aura fait une belle jambe d'avoir optimisé le chargement du niveau, c'est sur qu'on chargera le niveau rapidement, mais si c'est pour avoir 3 fps, c'est complétement crétin.
    Avant de dire je vais optimiser ma mutiplication de matrice il vaudrai mieux savoir si le travail pour générer les matrices, les utiliser par la suite est bien fait et ne peux plus être optimisé.
    A propos des nombre magique tu pourras demander à n'importe qui sur le forum, c'est pas bon d'en semer dans son code.

    De quel nombre magique tu parles? 4?
    Renseigne toi sur SSE... C'est toi même qui dit utiliser 3dnow dans un poste précédent! C'est peut-être parce que 3dnow est plus général que SSE?
    ben oui c'est ça un nombre magique !
    Je ne vois pas le rapport entre le SSE ou les instruction 3DNow! et le chiffre 4.
    tu as écris :
    Code :
    float *px=x, py=y, pz=z;for (int i=0, imax=n-4; i<imax; px+=4, py+=4, pz+=4, i+=4) _mm_store_ps(pz,_mm_add_ps(_mm_load_ps(px),_mm_load_ps(ps)));
    Il y a bien des 4 non ? c'est de ces 4 la dont je parle, tu décales des pointeurs dans la mémoire, non ? et ton 4 c'est parceque sizeof(float) t'as donné sur ta machine 4, mais si tu vas sur une vieille machine tu trouvera peut-être autre chose que 4!!!
    Et si ce 4 n'est pas sizeof(float) alors il va falloir que tu expliques car a mon avis je ne suis pas le seul à ne pas avoir tout compris.
    Tu veux bien optimiser ce code stp! Tu veux bien me dire en quoi la discussion sur une constante nous intéresse dans une discussion sur l'optimisation.
    Dis moi, tu les as critiqué, tous ceux qui proposent plus haut dans cette discussion de programmer en assembleur?
    Optimiser quoi ? c'est un exemple pour te monter quel nombre magique, à mon gout, on a le droit d'utiliser....
    Et pour ceux qui travail en assembleur il font ce qu'ils veulent, ils peuvent coder en assembleut si ils veulent moi je code en C++, et j'essaye de coder le mieux possible pour que le code généré soit le plus performant possible. Et pourquoi je les critiquerai, car il utilisent un autre langage du miens car une addition des deux entiers en assembleur est plus rapide qu'en C++, c'est n'importe quoi.
    Première grosse démo en construction :
    http://bitbucket.org/rafy/exo2/

  12. #132
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    J'ai plus envie de discuter avec toi.
    Je déteste être pris pour un débutant par un ... débutant.

    La seule explication sensée à ta remarque plus haut sur sizeof(int)==4, est que tu crois que l'instruction p+=4 ajoute 4 octet à l'adresse.
    Apprends que le "nombre magique 4" n'est pas sizeof(float) mais le nombre de floats calculés en parallèle dans un registre SSE soit 16/sizeof(float).

    J'ai remarqué ton poste posant des questions sur les références, c'est la B.A.BA: apprends le C++ avant de faire tes remarques secondaires qui ne tiennent pas compte du sujet. Tu as appris quelque part que les sizeof(..) sont différents d'un système à l'autre, à la bonne heure...

    J'ai illustré mes propositions d'exemples simples de quelques lignes, tu aurais préféré des pages complètes. Non il faut s'en tenir à l'idée.

    Tu critiques mes précisions sur la rapidité des 'if', alors que tu proposes plus haut d'utiliser de préférence ++i que i++ !!

    Tu dis qu'un programme prendrait 10ms alors qu'un autre 11ms: tu n'as aucune, mais alors aucune idée de l'optimisation.

    La multiplication de matrices est un algo simple, fréquemment utilisé pour comparer les performances de librairies mathématiques. Il illustre parfaitement l'optimisation des boucles.
    C'est trop compiqué pour toi?
    Relève le défi ou ferme la.

    C'est bon je me calme...

  13. #133
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Voilà, sujet clos...

  14. #134
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    Miles, pourquoi sujet clos?

  15. #135
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Parce que cela a déjà trop dégénéré. Si vous voulez continuer cette discussion tendue, faites-le par MP, merci.

  16. #136
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    Je me calme.
    Mais il faut bien que quelqu'un lui dise que l'instruction p+=4, n'ajoute pas 4 octets au pointeur mais 16=4*sizeof(float) octets. Sans quoi, effectivement, on comprend rien.

  17. #137
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Le truc, c'est que le 4 vient de BUFFER_SIZE / sizeof(float). La constante magique est bien éliminable.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  18. #138
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    Et ton BUFFER_SIZE il vient d'où? J'y peux rien si les registres SSE ont une taille fixe de 16 octets.
    Je veux bien faire toutes les constantes que vous voulez, mais cessez de ne parler que de cette constante alors que j'illustrais mon propos sur l'optimisation SSE par un exemple de 2 lignes.
    Si mon exemple n'est pas approximativement 4 fois plus rapide que la simple boucle, qu'on me le dise, et le prouve.
    De grâce, recentrons le sujet.

    Personne ne veut commenter ma 2ème suggestion qui innove par rapport au développement de boucle proposé encore plus haut dans ce forum? Cette suggestion consiste à:
    -développer la boucle
    -ne recalculer le déplacement du poineteur qu'une seule fois par boucle
    -d'utiliser des index constants.

  19. #139
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    Ben pour savoir si c'est plus rapide, il faut tester, c'est pas bien compliqué...
    Première grosse démo en construction :
    http://bitbucket.org/rafy/exo2/

  20. #140
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Je pensais que le compilo le faisais un minimum, ça...

Discussions similaires

  1. Réponses: 1
    Dernier message: 31/08/2014, 17h52
  2. Optimiser rapidité code
    Par bobosh dans le forum VBA Access
    Réponses: 2
    Dernier message: 28/08/2008, 16h12
  3. Optimisation code pour gagner en rapidité
    Par polodu84 dans le forum MATLAB
    Réponses: 2
    Dernier message: 05/03/2008, 15h32
  4. requete QBE / requete code : rapidité et index
    Par LostIN dans le forum Requêtes et SQL.
    Réponses: 11
    Dernier message: 05/07/2006, 08h54
  5. [rapidité du code] Mise a jour a partir d'un TQuery.
    Par goethe dans le forum Bases de données
    Réponses: 4
    Dernier message: 27/10/2004, 09h01

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