L'utilisation correcte de imbriquée #pragma omp for directives
Le code suivant fonctionne comme un charme avant de parallélisation OpenMP a été appliquée. En fait, le code suivant a été dans un état de boucle sans fin! Je suis sûr que la suite de mon utilisation incorrecte pour les directives OpenMP. Veuillez s'il vous plaît me montrer le bon chemin? Je vous remercie beaucoup.
#pragma omp parallel for
for (int nY = nYTop; nY <= nYBottom; nY++)
{
for (int nX = nXLeft; nX <= nXRight; nX++)
{
//Use look-up table for performance
dLon = theApp.m_LonLatLUT.LonGrid()[nY][nX] + m_FavoriteSVISSRParams.m_dNadirLon;
dLat = theApp.m_LonLatLUT.LatGrid()[nY][nX];
//If you don't want to use longitude/latitude look-up table, uncomment the following line
//NOMGeoLocate.XYToGEO(dLon, dLat, nX, nY);
if (dLon > 180 || dLat > 180)
{
continue;
}
if (Navigation.GeoToXY(dX, dY, dLon, dLat, 0) > 0)
{
continue;
}
//Skip void data scanline
dY = dY - nScanlineOffset;
//Compute coefficients as well as its four neighboring points' values
nX1 = int(dX);
nX2 = nX1 + 1;
nY1 = int(dY);
nY2 = nY1 + 1;
dCx = dX - nX1;
dCy = dY - nY1;
dP1 = pIRChannelData->operator [](nY1)[nX1];
dP2 = pIRChannelData->operator [](nY1)[nX2];
dP3 = pIRChannelData->operator [](nY2)[nX1];
dP4 = pIRChannelData->operator [](nY2)[nX2];
//Bilinear interpolation
usNomDataBlock[nY][nX] = (unsigned short)BilinearInterpolation(dCx, dCy, dP1, dP2, dP3, dP4);
}
}
OriginalL'auteur GoldenLee | 2011-11-24
Vous devez vous connecter pour publier un commentaire.
Ne pas imbriquer trop profonde. Généralement, il serait suffisante pour identifier un bon point pour la parallélisation et de s'en tirer avec une seule directive.
Certains commentaires et probablement à l'origine de votre problème:
(Conceptuellement), vous êtes à l'ouverture de plusieurs threads, chacun d'eux vous ouvrez le nombre de threads à nouveau dans la boucle for. Pour chaque fil dans la boucle for, vous pouvez ouvrir un grand nombre de threads de nouveau, et pour chacun de ceux-ci, vous ouvrez de nouveau beaucoup dans une autre boucle.
C'est
(thread (thread)*)+
dans un modèle d'appariement de mots; il devrait juste êtrethread+
Il suffit de faire une simple parallèle. Ne pas être à la fine, la parallélisation de la boucle externe, chaque thread doit fonctionner le plus longtemps possible:
Éviter les données et le cache de partage entre les threads (une autre raison pourquoi le fils ne devrait pas être trop fine sur vos données).
Si c'est en cours d'exécution stable et de bonne vitesse, vous pouvez l'affiner avec les différents algorithmes d'ordonnancement selon votre OpenMP carte de référence.
Et de mettre vos déclarations de variable où vous avez vraiment besoin d'eux. Ne pas remplacer ce qui est lu par de frère, de fils.
#pragma omp parallel default(shared) // Here you open several threads ... { #pragma omp for // <- syntax error:
vous avez tort phresnel. C'est tout à fait valable pour faire un parallèle pour la boucle. Que pragma raconte l'environnement parallèle pour être parallélisée maintenant. La combinaison deomp parallel
et suivantsomp for
est particulièrement utile si vous avez besoin de thread la répartition locale / initialisations, bien qu'ici, il n'est pas nécessaire et de faire un combinéomp parallel
vont certainement le faire.et oui pour beaucoup de nidification GoldenLee. Je pencherais pour la boucle externe, seulement. Vous êtes juste d'ouvrir un autre jeu de threads au sein d'un fil...
Merci pour votre explication détaillée sur l'utilisation d'OpenMP. Et désolé pour ma réponse tardive pour qu'il ne soit trop tard (en fait, je suis allé dormir). J'ai un test sur la base de votre suggestion. Mais le résultat let me down. Il est toujours dans le fonctionnement sans fin! Pourquoi? Pourriez-vous svp me donner d'autres conseils? Merci!!!!
Je vois, c'est nouveau pour moi. Merci pour cette remarque.
n'avez-vous pas besoin de déclarer nX comme privé dans la boucle de la parallélisation? j'.e:
#pragma omp parallel for private(nX)
OriginalL'auteur Sebastian Mach
Vous pouvez également l'effondrement de plusieurs boucles de manière efficace. Il y a des restrictions sur la boucle conditions: ils doivent être indépendants. Plus que tous les compilateurs prend en charge effondrement lexem. (Comme pour gcc avec OpenMP, il fonctionne.)
OriginalL'auteur Vyacheslav Napadovsky
Dans la pratique, il est généralement plus bénéfique pour paralléliser les plus boucle. La parallélisation de toutes les boucles internes peut vous donner trop de threads (si OpenMP bâtons avec le nombre de matériel des unités d'exécution, lorsqu'il n'est pas dit le contraire). Et le plus important - de la parallélisation de boucle intérieure wil les plus susceptibles de créer et de détruire les threads trop souvent, ce qui est une opération coûteuse. Votre PROCESSEUR doit exécuter le filetage des appels d'API au lieu de votre charge de travail.
Pas vraiment une réponse, mais j'ai pensé que je pourrais partager avec vous l'expérience.
OriginalL'auteur Violet Giraffe
Il y a des problèmes avec l'écriture de sécurité sur toutes les variables assignées dans la boucle interne. Chaque thread va essayer d'attribuer des valeurs à des variables, le plus probable que vous obtiendrez de la camelote. Par exemple, deux threads peut être mise à jour
dLon
dans le même temps, résultant dans le thread 1 passage de fil 2 de la valeur dansNavigation.GeoToXY(dX, dY, dLon, dLat, 0)
. Puisque vous appeler d'autres méthodes dans la boucle, les méthodes invoquées à bord d'une jonque arguments ne peut pas résilier.Pour résoudre ce problème, soit de déclarer des variables locales dans la boucle externe à droite après
omp parallel for
est appliquée ou, utilisez laprivate
des clauses commefirstprivate
pour obtenir OpenMP pour créer automatiquement des variables locales pour chaque thread. Dans le cas defirstprivate
, il faudra copier le initialisé de valeur mondiales. Par exemple,En savoir plus sur les clauses ici: https://computing.llnl.gov/tutorials/openMP/
OriginalL'auteur devil