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

C++ Discussion :

Optimisations non supportée pour certains PC. Normal ?


Sujet :

C++

  1. #1
    Membre chevronné
    Avatar de cpcdos
    Homme Profil pro
    Ingé/concepteur chez Capgemini. Alstom APTIS. Concepteur de Felly autonomous vehicle software.
    Inscrit en
    Mai 2010
    Messages
    588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingé/concepteur chez Capgemini. Alstom APTIS. Concepteur de Felly autonomous vehicle software.
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 588
    Points : 1 770
    Points
    1 770
    Billets dans le blog
    1
    Par défaut Optimisations non supportée pour certains PC. Normal ?
    Bonjour,

    J'ai actuellement à la maison, ces architectures suivantes : je vous donne l'année ça ira plus vite
    • Asus Rog i7 (2016)
    • Lenovo i5 (2016)
    • A8 (2015)
    • Asus i5 (2015)
    • Lenovo i3 (2014)
    • Sony vaio i5 (2012)
    • Sony P4 (2003)
    • VirtualBox
    • QEmu
    • VMWare


    Sous FreeDos 1.2 (DOS), j'ai un programme C++ compilé avec GCC 6.2/G++ en C++17 qui lit EN BOUCLE:128 fois un fichier de plus de 100ko sur le disque en traitant des opérations mémoires, grosses et petites allocations dynamiques, imports de fonctions externes, bref des opérations assez lourdes après la récupération du contenu du fichier.
    Ces opérations tous displayed sur le stdout, et elles prennent environs ~50ms chacune. Donc 6 secondes au total, selon le PC.

    Je maintient fortement que le code fonctionne parfaitement sur tous les PC cités ci-dessus sans optimisation, donc -O0.

    Mon problème
    J'ai donc voulu utiliser le flag -O (1, 2, ou 3) afin d'optimiser ces opérations. Voici le résultat :
    Je retiens que ces optimisations m'ont permis de gagner au moins 3x plus de temps, je passe de 6 secondes à 2 ou 3 secondes selon le PC.

    • Asus Rog i7 (2016) --> CRASH à la 1ere boucle
    • Lenovo i5 (2016) --> CRASH avant la boucle
    • A8 (2015) --> CRASH à la 2eme boucle
    • Asus i5 (2015) CRASH un peut hazardeusement
    • Lenovo i3 (2014) --> CRASH un peut hazardeusement, mais ça passe
    • Sony vaio i5 (2012) --> OK
    • Sony P4 (2003) --> OK
    • VirtualBox --> OK
    • QEmu --> OK
    • VMWare --> OK
    • DosBox --> OK


    CRASH se rapporte à un SIGSEGV ou un Page Fault

    J'ai essayé les architectures i386, i486, i586 et i686.. Même problème.. du coup je dois rester au -O0

    L'optimisation qui crash sur certains PC... Plus ils sont récents plus ça crash!! Utilisation du SSE mal géré ? Quelqu'un aurai une explication ?

    Merci
    Sébastien FAVIER
    Felly-software Autonomous vehicle software for everyone.
    co-kernel Cpcdos OSx un noyau 32bits simplifié et complet.. ou presque - Le fofo officiel c'est par ici.
    Les cours sur les systèmes c'est par là

  2. #2
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Je pencherais plutôt pour un comportement indéterminé dû à une erreur au sein du programme en question. Peut-on jeter un œil au code ?

  3. #3
    Membre chevronné
    Avatar de cpcdos
    Homme Profil pro
    Ingé/concepteur chez Capgemini. Alstom APTIS. Concepteur de Felly autonomous vehicle software.
    Inscrit en
    Mai 2010
    Messages
    588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingé/concepteur chez Capgemini. Alstom APTIS. Concepteur de Felly autonomous vehicle software.
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 588
    Points : 1 770
    Points
    1 770
    Billets dans le blog
    1
    Par défaut
    Merci pour ton aide :)

    Le code est gigantesque (ça fais 6 ans que je maintient et pas encore en git) en déboggant avec GDB, apparemment le plantage se fait souvent ici :
    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
    34
    35
    36
    37
    int cpinti_io::Lire_Fichier_complet(std::string Chemin, std::string MODE, std::string &_DONNEES)
    {
            // ***** Pour le moment c'est un INT pour une raison ultérieure ***** 
     
    	// Lire tout le contenu d'un fichier uniquement
    	// Retourne :
    	//	Si ok = Le contenu texte du fichier
    	//	Sinon = 0
     
     
    	// Definit les attributs temporaires		
    	std::ifstream Instance_Fichier;
     
    	// Choisir le mode d'ouverture
    	if(MODE.compare("RB") == 0)
    		Instance_Fichier.open (Chemin, std::ifstream::in | std::ifstream::binary);
    	else if(MODE.compare("R") == 0)
    		Instance_Fichier.open (Chemin, std::ifstream::in);
    	else
    		Instance_Fichier.open (Chemin);
     
    	// Tester
    	if (Instance_Fichier)
    	{
    		while (Instance_Fichier.good()) {
    			// *****  Pour une raison ultérieure je suis obligé de lire octets par octets ***** 
    			_DONNEES.push_back(Instance_Fichier.get());
    		}
    		Instance_Fichier.close();
    		return 1;
    	}
    	else
    	{
    		// Fichier non disponible
    		 return 0;
    	}
    }
    (GDB plante aussi.... il doit pas aimer -O1 2 3 non plus malgré le -g 1, 2, 3 ou -ggdb 1, 2, 3)
    Voici 2 photos depuis mon A8, via GDB.

    EN_BREF.JPG La fonction _ZN6cpinti9cpinti_io20Lire_Fichier_completENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6 Il s'agit de ma fonction Lire_Fichier_complet ci-dessus.

    PRECISEMENT.JPG Là où sa crash précisément, je suis aussi allé de step en step j'ai la même fonction "std::__basic_file<char>::xsgetn(char*, int)"

    ça fais partie de la lib standard cstring... elle pourrait être mise en cause ?

    Cette fonction va tout simplement lire un fichier au complet en utilisant "purement le c++17". Et pour une raison ultérieure je suis obligé de faire une while pour get octets par octets. Je ne vois aucun problème.. Surement dû à un précédent buffer overflow avant l'appelle de cette fonction qui a peut être écrasé la HEAP, ou la .DATA ou je ne sais quelle mémoire ce p'tit c** me fait planter.. Ce qui est fort c'est si j'optimise mon code, et que plus le PC est récent plus ça plante facilement.. :(
    Sébastien FAVIER
    Felly-software Autonomous vehicle software for everyone.
    co-kernel Cpcdos OSx un noyau 32bits simplifié et complet.. ou presque - Le fofo officiel c'est par ici.
    Les cours sur les systèmes c'est par là

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je ne vois rien dans la fonction qui contienne un bug flagrant, et en plus vue la durée de vie ça ne peut pas être le flux qui est invalide... et pourtant c'est le flux qui plante (ton appel à get()). Vraiment bizarre, surtout si les seules autres opérations que tu fais, c'est l'écriture dans la chaîne (qui met tout son contenu sur le tas)...

    Ton programme est-il mono-thread?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 379
    Points
    11 379
    Billets dans le blog
    10
    Par défaut
    Salut!

    Tu nous as mis un code minimal, pour la compréhension de l'algo utilisé, par contre je me pose une question, est-ce que ce code minimal plante aussi?

    EDIT:

    Ou bien il s'agit de tout le code de ta fonction, telle qu'implémentée en vrai?
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    L'utilisation de good pour boucler n'est pas bonne. Le flux peut être dans un bon état, tu boucles, espères récupérer des données, mais y'en a plus et ça plante.
    Préfère utiliser les opérateurs de lecture de flux, >>, et vérifier le retour de l'opérateur à la place.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char o;
    while (input >> o) { donnees.push_back(o); }
    Aussi quelle serait cette "raison ultérieur pour être obligé de lire par octet" ? Si ton code ne fait vraiment que boucler pour tout lire ?
    Enfin il serait préférable de regarder la taille du fichier pour réserver la mémoire.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Membre chevronné
    Avatar de cpcdos
    Homme Profil pro
    Ingé/concepteur chez Capgemini. Alstom APTIS. Concepteur de Felly autonomous vehicle software.
    Inscrit en
    Mai 2010
    Messages
    588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingé/concepteur chez Capgemini. Alstom APTIS. Concepteur de Felly autonomous vehicle software.
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 588
    Points : 1 770
    Points
    1 770
    Billets dans le blog
    1
    Par défaut
    Merci pour vos réponse!

    @Médinoc

    Vraiment bizarre
    On est d'accord ...


    Ton programme est-il mono-thread?
    à l'origine il est multi-thread, j'ai donc temporairement supprimé/bloqué toutes interruptions, IRQs, plus rien est multi-threadé, quitte à faire un mutexe, seamphore, ou une Entercriticalsection sur cette fonction pour le rendre purement "mono-thread" afin de voir si éventuellement il s'agit d'un autre thread ou d'une interruption .. Rien à faire c'est la même chose...


    @dragonjoker59
    Tu nous as mis un code minimal, pour la compréhension de l'algo utilisé
    Ou bien il s'agit de tout le code de ta fonction, telle qu'implémentée en vrai?
    C'est une fonction dans une classe que mes autres fonctions instancie depuis shared_ptr<> et l'utilisent et c'est la seule qui plante
    Le reste c'est d'autres fonctions qui n'ont rien à voir
    par contre je me pose une question, est-ce que ce code minimal plante aussi?
    Bonne question!
    Je vais essayer ce soir de sortir ce code pour le tester seul avec optimisations et mes bêtes allergiques. Je te tiens au courant.


    @Bousk
    Merci pour ta réponse, je test tout ça ce soir! Je te tiens au courant aussi.
    La raison est pas encore très bien déterminée.. ni sure, ça serai pour les mois à venir, plus au niveau la conversion à la source UTF8 <--> 16 <--> ASCII compatible. Afin d'éviter de re-traiter mon buffer, question de performances quand il s'agit de traiter des petit comme des gros fichiers


    Enfin il serait préférable de regarder la taille du fichier pour réserver la mémoire.
    Exact! Avant de donner la référence d'un std::string &_DONNEES j'ai "essayé" de resizer _DONNEES selon la taille du fichier source, mais ça change pas, surtout que std::string "gère son buffer" donc il a l'air de re-sizer.


    Au concret
    Est-ce l'optimisation de GCC/G++ à tendance à utiliser des jeux d'instructions différentes / Assez "critiques" ? x87 ? SSE 2, 3 > Core2 , 4 ? SMID/MMX ? AVE ?...
    <faché>Ou les constructeur qui nous em*rde!? </faché>
    Sébastien FAVIER
    Felly-software Autonomous vehicle software for everyone.
    co-kernel Cpcdos OSx un noyau 32bits simplifié et complet.. ou presque - Le fofo officiel c'est par ici.
    Les cours sur les systèmes c'est par là

  8. #8
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 156
    Points
    3 156
    Par défaut
    Hello

    Les optimisations ne sont sans doute pas à l'origine du problème, mais sûrement révélatrice d'un problème peu visible. Je serais toi, après avoir appliqué les suggestions de Bousk, je passerais un coup de Valgrind et de AddressSanitizer pour voir ce que ça donne. Tu peux compiler en -02 et garder tout de même les symboles de debug pour avoir une trace qui a du sens. Si la base de code est grosse, il risque d'y avoir pas mal de remontées, mais un plantage donne souvent de bonnes infos dans valgrind.
    Find me on github

  9. #9
    Membre chevronné
    Avatar de cpcdos
    Homme Profil pro
    Ingé/concepteur chez Capgemini. Alstom APTIS. Concepteur de Felly autonomous vehicle software.
    Inscrit en
    Mai 2010
    Messages
    588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingé/concepteur chez Capgemini. Alstom APTIS. Concepteur de Felly autonomous vehicle software.
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 588
    Points : 1 770
    Points
    1 770
    Billets dans le blog
    1
    Par défaut
    Merci pour ta réponse, Valgrind c'est sous Windows ou Linux, je ne pourrai pas exécuter mon code dans les conditions réelles actuelles (FreeDos 1.2)
    J'ai un penchant pour AddressSanitizer qui apparemment est inclut depuis GCC 4.8, je jetterai un coup d'oeil après avoir testé les solutions de dragonjoker59 et Bousk
    Sébastien FAVIER
    Felly-software Autonomous vehicle software for everyone.
    co-kernel Cpcdos OSx un noyau 32bits simplifié et complet.. ou presque - Le fofo officiel c'est par ici.
    Les cours sur les systèmes c'est par là

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    std::string "gère son buffer" donc il a l'air de re-sizer
    Bien sûr, tout comme vector.
    Ca ne change pas le problème, augmenter la taille c'est une opération coûteuse.
    Et tu parles d'être en multi-thread, comment cette fonction est utilisée ? Tu as une variable en paramètre out, qui est modifiée et dont la représentation interne est également modifiée grandement. Si tu es en train de la parcourir, et que l'autre thread la resize, tous tes itérateurs etc sont invalidés.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  11. #11
    Membre chevronné
    Avatar de cpcdos
    Homme Profil pro
    Ingé/concepteur chez Capgemini. Alstom APTIS. Concepteur de Felly autonomous vehicle software.
    Inscrit en
    Mai 2010
    Messages
    588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingé/concepteur chez Capgemini. Alstom APTIS. Concepteur de Felly autonomous vehicle software.
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 588
    Points : 1 770
    Points
    1 770
    Billets dans le blog
    1
    Par défaut
    Merci pour ta réponse

    comment cette fonction est utilisée ?
    Comme ceci par exemple (en plus il fait du std::string-->char) :
    J'ai sabré le code d'origine (log des activités) en gardant l’essentiel, s'il reste ou manque des déclarations je m'excuse

    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
    /*
    const char* Chemin <-- Chemin d'acces au fichier
    const char* Mode <-- Mode 'RB'
    char* _DONNEES <-- Contient déjà la référence sizé 
    */
     
    	int Resultat_int;
    	std::string Resultats; // Ma reference "_DONNEES"
    	std::string Chemin_STR = std::string(Chemin);
    	std::string Mode_STR = std::string(Mode);
     
    	std::shared_ptr<cpinti::cpinti_io> instance_io(new cpinti::cpinti_io);
     
    	if (instance_io != NULL)
    	{
     
    		if(instance_io->Lire_Fichier_complet(Chemin_STR, Mode_STR, Resultats))
    		{
    			unsigned int Taille_Fichier = static_cast<unsigned int>(Resultats.size());
     
    			// Passer du std::string au char (Oui je sais qu'il existe c_str() c'était pour tester un truc)
    			for(unsigned int boucle = 0; boucle <= Taille_Fichier; boucle++)
    				_DONNEES[boucle] = Resultats[boucle];
    			Resultat_int = 0; // OK
    		}
    		else
    		{
    			Resultat_int = -2; // Probleme de lecture
    		}
    	}
    	else{
    		Resultat_int = -1; // Probleme memoire
    	}
    Je rappelle que ce code fonctionne sur TOUS les PC cités sur le premier post sans optimiser

    Et tu parles d'être en multi-thread
    selon les besoins utilisateurs, un ou plusieurs threads sont crées, chaque threads font leur boulo. Dés qu'une fonction/thread a besoin d'informations dans un fichier, il va utiliser seulement ma fonction Lire_Fichier_complet()
    Sébastien FAVIER
    Felly-software Autonomous vehicle software for everyone.
    co-kernel Cpcdos OSx un noyau 32bits simplifié et complet.. ou presque - Le fofo officiel c'est par ici.
    Les cours sur les systèmes c'est par là

  12. #12
    Membre chevronné
    Avatar de cpcdos
    Homme Profil pro
    Ingé/concepteur chez Capgemini. Alstom APTIS. Concepteur de Felly autonomous vehicle software.
    Inscrit en
    Mai 2010
    Messages
    588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingé/concepteur chez Capgemini. Alstom APTIS. Concepteur de Felly autonomous vehicle software.
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 588
    Points : 1 770
    Points
    1 770
    Billets dans le blog
    1
    Par défaut
    Résultat de vos solutions : Je vous ai dérangé pour rien

    @Bousk
    Le problème reste le même, mais c'est pas plus mal d'avoir le minimum de ligne Merci!

    @dragonjoker59
    J'ai sabré tout mon code pour exécuter seulement ma fonction "qui est cencé planter" et bien en -O3, la fonction fonctionne parfaitement sur mes PC.

    Conclusion
    Le problème doit venir d'avant, je pense qu'un moment donné, le code exécuté avant l'appel de fonction a dû bousiller une zone de mémoire, stack overflow ou je sais pas mais le problème est effectivement pas cette fonction mais bien d'autre pars...
    Je peux rester en -O0 et le sujet sera clos mais bon .. balader un code avec un problème... bref une fois trouvé je pourrais optimiser mon code.

    Je vais tenter de me pencher dessus en éliminant le maximum d'instances dans la HEAP, et autres.. je vous tiendrai au courant de ma trouvaille !

    Merci à tous le monde pour votre aide !!!


    Concernant AddressSanitizer, il faut la librairie LIBasan.a, j'ai trouvé un petit tuto, 3 versions en ligne, ici, ici et ici mais ....
    Nom : snip_20161102223904.png
Affichages : 211
Taille : 24,5 Ko
    par exemple il me cherche __asan_init alors que dans le fichier LIB demandé, j'ai seulement __asan_init_V1
    Je me tate à edit manuellement les symbols, a moins que tu as une solution ?
    Sébastien FAVIER
    Felly-software Autonomous vehicle software for everyone.
    co-kernel Cpcdos OSx un noyau 32bits simplifié et complet.. ou presque - Le fofo officiel c'est par ici.
    Les cours sur les systèmes c'est par là

Discussions similaires

  1. Réponses: 0
    Dernier message: 18/03/2011, 12h33
  2. Fonctionnalité non supportée pour un Locate !
    Par teZone dans le forum Débuter
    Réponses: 8
    Dernier message: 02/06/2009, 23h06
  3. index.php non trouvé pour certains contrôleurs !
    Par citronbleu-v dans le forum Apache
    Réponses: 11
    Dernier message: 24/01/2009, 14h41
  4. index.php non trouvé pour certains contrôleurs !
    Par citronbleu-v dans le forum Zend Framework
    Réponses: 9
    Dernier message: 24/01/2009, 12h18
  5. Réponses: 5
    Dernier message: 20/08/2006, 02h55

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