6
votes

OpenMP itération pour boucle dans la région parallèle

Désolé si le titre est un grand pas clair. Je ne sais pas très bien comment le mot.

Je me demande s'il y a une façon de faire ce que je peux faire ce qui suit: xxx

ignorer des choses telles que omettre des spécificateurs privés Dans la boucle pour la boucle, est-ce que je peux faire des fils de fourche à l'extérieur de ma boucle extérieure afin que je puisse simplement parlementer la boucle intérieure? De ma compréhension (s'il vous plaît, corrigez-moi si je me trompe), tous les threads exécuteront la boucle extérieure. Je ne sais pas le comportement de la boucle intérieure, mais je pense que le pour distribuera des morceaux à chaque threads qui le rencontrent.

Ce que je veux faire n'est pas à faire Fork / Joindre itérations fois mais faites-la une fois dans la boucle extérieure. Est-ce la bonne stratégie pour le faire?

Et s'il y avait une autre boucle extérieure qui ne devrait pas être parallélédée? C'est ... xxx

Ce serait génial si quelqu'un me dirigeait à un exemple d'une application importante parallèle à l'aide d'OpenMP afin que je puisse mieux comprendre les stratégies d'employer lorsque vous utilisez OpenMP. Je ne peux pas sembler trouver.

Clarification: Je recherche des solutions qui ne changent pas de commandes en boucle ni impliquent des considérations de blocage, de mise en cache et de performance générale. Je veux comprendre comment cela pourrait être fait dans OpenMP sur la structure de la boucle comme spécifié. Le // fait quelque chose peut avoir ou peut ne pas avoir de dépendances, supposer qu'ils le font et que vous ne pouvez pas déplacer les objets.


3 commentaires

Peut-être que vous pouvez donner un exemple de ce que vous voulez faire. Je veux dire remplir le code // faire quelque chose


@raxman, ça ne va pas aider. Ceci est censé être une demande de solution générale à un tel problème, pas une solution pour une application particulière.


Vous pourriez aller de l'avant et upvote / accepter une réponse. On dirait que des gens mettent des efforts et ont eu des upvotes assez minimes pour tout cela.


3 Réponses :


1
votes

Je ne suis pas sûr de pouvoir répondre à votre question. Je n'ai utilisé que OpenMP depuis quelques mois maintenant, mais quand j'essaie de répondre à des questions comme celle-ci, je fais des tests de Hello World Printf comme je le montre ci-dessous. Je pense que cela peut aider à répondre à vos questions. Essayez également #pragma oomp pour le même et voyez ce qui se passe.

Assurez-vous simplement quand vous "// faire quelque chose et // faire quelque chose d'autre" que vous n'écrivez pas à la même adresse mémoire et créer une condition de course. En outre, si vous faites beaucoup de lecture et que vous avez besoin de penser à utiliser efficacement le cache. xxx

en termes de performance que vous voudrez peut-être envisager de fusionner votre boucle comme celle-ci. xxx


0 commentaires

0
votes

Il est difficile de répondre car cela dépend vraiment des dépendances de votre code. Mais une manière générale de résoudre ce problème est d'inverser la nidification des boucles, comme ceci:

#pragma omp parallel
{
    #pragma omp for
    for (int j = 0; j < N; j++) {
        for (int i = 0; i < iterations; i++) {
            // Do something
        }
    }
}


0 commentaires

3
votes

La façon dont vous avez manipulé les deux boucles vous ressemble, dans le sens où il obtient le comportement que vous vouliez: la boucle extérieure n'est pas paralléléée, tandis que la boucle interne est.

Pour mieux clarifier ce qui se passe, je "J'essaierai d'ajouter des notes à votre code: xxx

la barrière implicite est un point de synchronisation où les threads attendent l'un pour l'autre. En règle générale du pouce, il est donc préférable de paralléliser boucles extérieures plutôt que des boucles intérieures , car cela créera un point de synchronisation unique pour les itérations itérations * n itérations ( au lieu des points itérations que vous créez ci-dessus).


6 commentaires

La boucle extérieure est censée spécifier plusieurs passes de certains algorithmes, de sorte qu'il ne peut donc pas parallédisé. Désolé si je n'étais pas clair à ce sujet.


La boucle extérieure n'est pas parallélédisée, car il n'y a pas de directive de travail sur elle


Si vous exécutez les tests «Hello World Printf» avec le code que j'ai suggéré qu'il montre tout cela. Vous pouvez voir que si vous ajoutez l'étiquette N2AIT que la barrière est supprimée. En d'autres termes, sans néant la boucle extérieure en non parallélisé et avec elle.


@raxman La boucle extérieure est jamais parallèle. Avec la clause NOWAIT Vous supprimez le point de synchronisation, c'est tout.


D'accord, mais peut-être que c'est une terminologie car la boucle extérieure fonctionne sur différents fils dans les deux cas. La seule façon dont il fonctionnera dans un seul fil (indéfini) consiste à déplacer les pragmas OMM à l'intérieur de la boucle extérieure.


Je pense que je comprends ce que tu veux dire. Vous voulez dire que les itérations ne sont jamais divisées entre les fils de la boucle extérieure. Alors ce que j'ai écrit était faux. Néanmoins, la boucle extérieure est toujours exécutée dans différents fils.