2010-05-24 4 views
0

I ont un bloc de programme comme:synchronisation construire à l'intérieur de pragma pour

for (iIndex1=0; iIndex1 < iSize; iIndex1++) 
    { 
     for (iIndex2=iIndex1+1; iIndex2 < iSize; iIndex2++) 
     { 
      iCount++; 
      fDist =(*this)[iIndex1].distance((*this)[iIndex2]); 
      m_oPDF.addPairDistance(fDist); 

      if ((bShowProgress) && (iCount % 1000000 == 0)) 
       xyz_exception::ui()->progress(iCount, (size()-1)*((size()-1))/2); 

     } 
    } 
} 
} 

j'ai essayé paralléliser la boucle interne et externe et en mettant iCount dans une région critique. Quelle serait la meilleure approche pour paralléliser cela? Si j'emballe iCount avec omp single ou omp atomic alors le code donne une erreur et j'ai compris que ce serait invalide dans omp pour. Je suppose que j'ajoute beaucoup de trucs superflus pour paralelliser ça. Besoin d'un conseil ...

Merci,

Sayan

Répondre

1

Si j'interprète correctement vos intentions que vous voulez utiliser iCount pour dire votre programme quand (tous les 10^6 opérations) de mettre à jour une interface utilisateur? Et iCount est global, tous les threads sont de partager la valeur et vous voulez maintenir sa cohérence? Je chercherais un moyen de remplacer ce compteur global par des compteurs privés à chaque thread et demanderais aux threads d'envoyer un message pour mettre à jour l'interface utilisateur indépendamment les uns des autres. Si vous insistez pour utiliser un compteur global, vous devrez, d'une manière ou d'une autre, synchroniser les threads, ce qui sera un coup de performance. Oui, vous pouvez écrire votre programme de cette façon, mais je ne le recommande pas.

Si vous n'aimez pas l'idée de tous les threads qui envoient des messages à l'interface utilisateur, peut-être qu'un seul thread peut le faire; Si un thread est 1/4 dans le programme, les autres threads le sont aussi (approximativement).

0

Merci encore Mark. J'ai essayé les approches que vous avez suggérées. J'ai mis réduction (+: iCount) et j'ai essayé aussi d'emballer iCount ++ autour de pragma critique, et oui c'est un coup de performance (aussi je n'ai vu aucune accélération). En outre, j'ai laissé un thread manipuler iCount, mais les approches que j'ai faites n'entraînent aucune accélération.

Je m'attendais à ce que si je mettais un pragma autour de la boucle interne, et déclariez iCount comme variable de réduction, je remarquerais au moins une accélération. Mon objectif est l'exécution parallèle de ces déclarations pour une Index1 paire Index2:

 fDist =(*this)[iIndex1].distance((*this)[iIndex2]); 
     m_oPDF.addPairDistance(fDist); 

qui pourrait avoir un impact sensiblement le temps d'exécution du programme.

+0

Ce que je vous suggère de faire est oublier iCount pendant un certain temps, paralléliser votre boucle extérieure et obtenir une certaine accélération. Une fois que vous avez fait que vous pouvez expérimenter des façons de mettre en œuvre votre compteur et examiner leurs effets sur speedup. En ce moment, je pense que vous essayez de prendre des pas de géant lorsque votre niveau d'expérience avec OpenMP vous suggère devriez prendre des petits pas. –

0

Merci beaucoup Mark. J'ai enlevé iCount et ai rendu la boucle externe parallèle, mais je creuse le code puisque je n'observe aucune accélération quand on la compare à la version sérielle.

Je voudrais saisir cette occasion pour obtenir un effet de base clarifié ... dans un environnement de boucle imbriquée comme ci-dessus ... que l'on pourrait généralement mieux:

  1. Faire le parallèle de la boucle intérieure

    pragma omp parallèle
    pour (... i ...)
    pragma omp pour
    pour (... j ...)

  2. Rendre la boucle externe parallèle, (juste un parallèle pragma pour ... avant la boucle externe)

  3. Utilisation de Collapse (pour Omp 3.0)

Merci
Sayan