2017-10-17 27 views
0

Donc, j'ai à peu près ce code:OpenMP; l'action entre les boucles imbriquées

for (int i = 0; i != 10000; ++i) { 
    doAction(i); 
    for (int j = 0; j != 10000; ++j) { 
     ... 
    } 
} 

Et je veux parallellize à l'aide d'OpenMP. Si je comprends bien, un simple collapse ne fera pas dans ce cas; mes tentatives pour utiliser les #pragma omp for s n'ont pas non plus porté leurs fruits. Y at-il un moyen simple de paralléliser cela facilement ou dois-je recourir à appeler doActioni*j fois?

+1

Que diriez-vous de remplacer! = Par tim18

+0

@ tim18 Qu'est-ce que c'est censé faire? J'ai toujours supposé qu'ils sont équivalents dans ce contexte. En outre, je ne vois pas comment cela est lié à la partie en boucle imbriquée de la question – Akiiino

+1

** [A]: ** Considérez-vous un appel à une fonction 'doAction (i);' pour représenter le * (cit .) "action ** entre ** boucles imbriquées" *? ** [B]: ** Comment avez-vous eu l'idée que le code 'doAction (i)' est appelé ** 'i * j' ** fois? ** [C]: ** Quel est le traitement réel dans '...'? Le code MCVE devrait représenter un exemple reproductible. Comment valider un tel morceau de code, sans avoir la possibilité de confirmer/rejeter la possibilité d'organiser une exécution de code "juste" - ** '[CONCURRENT]' ** ou vrai - ** '[PARALLEL]' **, quand ceci morceau du code MCVE est réellement manquant? – user3666197

Répondre

1

La manière simple de paralléliser, utilisez uniquement OpenMP pour la boucle externe.

La mise à l'identique de la numérotation vers le bas n'est pas une bonne chose, car la synchronisation de thread & surcharge la planification des tâches. Lorsque vous divisez une grande tâche liée à un CPU en morceaux pour une exécution en parallèle, idéalement, les pièces doivent être aussi grandes que possible tout en utilisant tous les cœurs de CPU disponibles la plupart du temps.

P.S. Si vous avez OpenMP 4, pour la boucle interne, vous pouvez vouloir #pragma omp simd au lieu de parallel. La boucle externe doit toujours être parallel. De cette façon, vous utiliserez les deux types de parallélisme en même temps, la boucle externe étant parallélisée entre les cœurs, la boucle interne étant parallélisée sur les lignes SIMD. Théoriquement, c'est souvent le moyen le plus rapide de calculer les choses.

+0

C'est une bonne réponse. Bien que cela ne soit pas détaillé, la recommandation est juste. Paralléliser comme grain fin (boucles intérieures) si nécessaire (pour exposer suffisamment d'éléments de travail séparés et équilibrer la charge), mais paralléliser en tant que gros grain que possible (pour garder les frais généraux faible). Cela m'intrigue pourquoi cela a été voté. – Zulan