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 :

OpenMP ralentit au lieu de booster


Sujet :

Threads & Processus C++

  1. #21
    Membre éprouvé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

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

    Informations forums :
    Inscription : Mars 2009
    Messages : 552
    Points : 1 060
    Points
    1 060
    Par défaut
    Citation Envoyé par rAyyy Voir le message
    mon proc n'est pas capable de faire de l'hyperthreading.
    Ca ne veut pas dire qu'il ne peut pas faire du multi-threading...

    Citation Envoyé par rAyyy Voir le message
    Mais il a une puce graphique(et j'ai une carte graphique). Du coup au début je pensai utiliser OpenCL mais je me suis dit que ça serai plus simple pour commencer avec OpenMP.
    Je te conseillerais de maîtriser d'abord les threads et d'avoir des notions sur les algorithmes parallèles avant de te lancer là dedans...

  2. #22
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2012
    Messages : 25
    Points : 14
    Points
    14
    Par défaut
    Citation Envoyé par Aleph69 Voir le message
    Je pense que ce serait une bonne chose que tu fasses sauter ton instruction conditionnelle, soit en faisant un peu plus de calculs, soit en procédant à une fission de ta boucle interne en deux boucles.
    Pourquoi? Les instruction conditionnelle sont très coûteuse?
    Ou c'est pour pas qu'un thread tourne pour rien?

    A vrai dire j'ai un peu réfléchi. Je calcul à chaque fois la distance c'est à dire nmb*nmb fois alors qu'il n'y a que ( (nmb-1)*nmb )/2 distance différente donc je pensai rajouter d'autre condition.
    C'est mal?

  3. #23
    Membre expérimenté
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Points : 1 685
    Points
    1 685
    Par défaut
    Salut,

    il n'y a rien de mal mais tu n'aides pas ton compilateur à optimiser tes boucles.
    Et finalement avec les caches c'est parfois plus efficace de calculer un terme en plus quitte à le soustraire à la fin du calcul et à introduire ainsi une petite erreur qui, sauf cas extrême, est de l'ordre de la précision machine.

  4. #24
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2004
    Messages : 329
    Points : 608
    Points
    608
    Par défaut
    C'est ce qu'on appelle du "N-body", assez classique comme algo. Ici ce ne sera pas le coût de lancement des threads mais le coût de synchronisation à chaque tour de la boucle externe qui sera prépondérant. De plus la réduction a un coût également... La dernière version écrite par "bretus" permet de paralléliser la boucle externe, ça devrait être bien mieux niveau perf.

  5. #25
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2004
    Messages : 329
    Points : 608
    Points
    608
    Par défaut
    Autre chose: il vaut mieux séparer dans deux tableaux plutôt que d'avoir des membres "old_position" et "new_position" dans la structure, moins de traffic sur les caches je pense

  6. #26
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2012
    Messages : 25
    Points : 14
    Points
    14
    Par défaut
    Citation Envoyé par Joker-eph Voir le message
    Autre chose: il vaut mieux séparer dans deux tableaux plutôt que d'avoir des membres "old_position" et "new_position" dans la structure, moins de traffic sur les caches je pense
    Juste pour être précis Planète est une une class.

    J'ai modifier le code pour faire moins de calcul
    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
     void incrementation(Planete* A, int nmb)
    {
      int i;
      int l;
     
    for(l=0;l<=nmb-1;l++)
    {
     
    		float Alx_now = A[l].x_now ;
    		float Aly_now = A[l].y_now ;
    		float Alz_now = A[l].z_now ;
     
    		for(i=l+1;i<=nmb-1;i++)
        {
     
     
    				float dx = A[i].x_now - Alx_now ;	
    				float dy = A[i].y_now - Aly_now ;
    				float dz = A[i].z_now - Alz_now ;
    				float m  = A[i].masse ; 
     
    				float distance = dx*dx + dy*dy + dz*dz + 1.0f ;
     
    				float factor = 1.0f / ((distance)*sqrt(distance)) ; 
     
    				float tempox =( G * m * dx ) * factor;
    				float tempoy =( G * m * dy ) * factor;
    				float tempoz =( G * m * dz ) * factor;
     
    				A[l].truc1 += tempox ;
    				A[l].truc2 += tempoy ;
    				A[l].truc3 += tempoz ;
     
    				A[i].truc1 -= tempox ;
    				A[i].truc2 -= tempoy ;
    				A[i].truc3 -= tempoz ;
     
     
             }
    }
     
     
    for(l=0;l<=nmb-1;l++)
    { 
     
    A[l].x_after= A[l].truc1*PAS*PAS - A[l].x_past + 2*A[l].x_now;
    A[l].y_after= A[l].truc2*PAS*PAS - A[l].y_past + 2*A[l].y_now;
    A[l].z_after= A[l].truc3*PAS*PAS - A[l].z_past + 2*A[l].z_now;
     
        A[l].x_past=A[l].x_now;
        A[l].y_past=A[l].y_now;
        A[l].z_past=A[l].z_now;
     
        A[l].x_now=A[l].x_after;
        A[l].y_now=A[l].y_after;
        A[l].z_now=A[l].z_after;
     
        A[l].x_after=0;
        A[l].y_after=0;
        A[l].z_after=0;
     
    	A[l].truc1 = 0 ;
    	A[l].truc2 = 0 ;
    	A[l].truc3 = 0 ;
     
    }
    }
    J'essayerai un peu plus tard de mettre la parallélisation. Mais je pense que mon choix de mettre truc1 / 2 / 3 dans planète n'est pas terrible pour ça. Je n'ai pas d'idée de comment est géré un tableau (ou une class d’ailleurs) par openMP.

    De ce que j'ai vu impossible de faire une réduction avec un tableau en C/C++

    Je pense que je vais créer un tableau de taille nmb*nmb*3 et je vais faire ce que fait la réduction dans la 2eme boucle.
    Mais je sais pas si c'est vraiment efficace.

  7. #27
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2012
    Messages : 25
    Points : 14
    Points
    14
    Par défaut
    Bon étant donné que j'ai vu que les tableau ne pouvait pas subir de réduction avec openMP j'ai encore modifié mon code


    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    void incrementation(Planete* A, int nmb,float*** tableau)
    {
     
      int i;
      int l;
     
     for(l=0;l<=nmb-1;l++)
    {
    		float Alx_now = A[l].x_now ;
    		float Aly_now = A[l].y_now ;
    		float Alz_now = A[l].z_now ;
     
    		float truc1=0.0f;
    		float truc2=0.0f;
    		float truc3=0.0f;
     
    		for(i=l+1;i<=nmb-1;i++)
        {
     
    				float dx = A[i].x_now - Alx_now ;	
    				float dy = A[i].y_now - Aly_now ;
    				float dz = A[i].z_now - Alz_now ;
    				float m  = A[i].masse ; 
     
    				float distance = dx*dx + dy*dy + dz*dz + 1.0f ;
     
    				float factor = 1.0f / ((distance)*sqrt(distance)) ; 
     
    				float tempox =( G * m * dx ) * factor;
    				float tempoy =( G * m * dy ) * factor;
    				float tempoz =( G * m * dz ) * factor;
     
     
    				tableau[l][i][0]=tempox;
    				tableau[l][i][1]=tempoy;
    				tableau[l][i][2]=tempoz;
     
    				tableau[i][l][0]=-tempox;
    				tableau[i][l][1]=-tempoy;
    				tableau[i][l][2]=-tempoz;
        }
     
    }
     
    for(l=0;l<=nmb-1;l++){
      	for(i=0;i<=nmb-1;i++)
    	{ 
    		A[l].truc1 += tableau[l][i][0] ;
    		A[l].truc2 += tableau[l][i][1] ;
    		A[l].truc3 += tableau[l][i][2] ;
    	}
    }
     
    for(l=0;l<=nmb-1;l++)
    { 
     
    A[l].x_after= A[l].truc1*PAS*PAS - A[l].x_past + 2*A[l].x_now;
    A[l].y_after= A[l].truc2*PAS*PAS - A[l].y_past + 2*A[l].y_now;
    A[l].z_after= A[l].truc3*PAS*PAS - A[l].z_past + 2*A[l].z_now;
     
     
        A[l].x_past=A[l].x_now;
        A[l].y_past=A[l].y_now;
        A[l].z_past=A[l].z_now;
     
        A[l].x_now=A[l].x_after;
        A[l].y_now=A[l].y_after;
        A[l].z_now=A[l].z_after;
     
        A[l].x_after=0;
        A[l].y_after=0;
        A[l].z_after=0;
     
    	A[l].truc1 = 0 ;
    	A[l].truc2 = 0 ;
    	A[l].truc3 = 0 ;
     
    }
    }
    Ça marche plutôt bien.
    Mais quand je met
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #pragma omp parallel for
    (car il n'y a plus de réduction) sur la première boucle ça bug. erreur du type impossible d’écrire à l'emplacement mémoire machin.
    Donc j'imagine que openMP aime pas mon pointeur de pointeur de pointeur

    Que puedo hacer senor?

  8. #28
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2004
    Messages : 329
    Points : 608
    Points
    608
    Par défaut
    Citation Envoyé par rAyyy Voir le message
    Juste pour être précis Planète est une une class.
    La différence entre classe et structure est que l'accès aux membres est privé par défaut pour la classe et public pour la structure. Là tout semble public et "Planet" est utilisée comme une structure.
    Bref ça ne change rien à mon commentaire qui portait sur l'organisation des données en mémoire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    De ce que j'ai vu impossible de faire une réduction avec un tableau en C/C++ :cry:
    OpenMP 4.0 il me semble...

    Je pense que je vais créer un tableau de taille nmb*nmb*3 et je vais faire ce que fait la réduction dans la 2eme boucle.
    Mais je sais pas si c'est vraiment efficace.
    J'ai l'impression que tu compliques les choses, la version de bredus me semble pas mal sur le principe.

Discussions similaires

  1. [Designer 6i]: 6Bouton de navigation au lieu de 5
    Par patmaba dans le forum Designer
    Réponses: 7
    Dernier message: 30/07/2007, 07h49
  2. Pourquoi me conseille t'on le C au lieu de VB ?
    Par hicham000 dans le forum Langages de programmation
    Réponses: 16
    Dernier message: 11/06/2004, 19h38
  3. [BDD] renvoyer une chaine vide au lieu de null
    Par cmoulin dans le forum JDBC
    Réponses: 6
    Dernier message: 06/05/2004, 11h38
  4. Equivalent IN ms avec un ET au lieu du OU ds la lste
    Par Pompil dans le forum Requêtes
    Réponses: 4
    Dernier message: 04/03/2004, 21h20
  5. [TOMCAT] affichage arborescence au lieu d'éxécuter la servle
    Par lombra dans le forum Tomcat et TomEE
    Réponses: 4
    Dernier message: 13/08/2003, 13h30

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