Alternatives à std :: vector dans une boucle For parallèle OpenMP
Dans OpenMP, travailler avec un std :: vector partagé dans un parallèle pour la boucle peut poser des problèmes de performances. Cet article explore les alternatives potentielles qui offrent des avantages en termes de vitesse, en particulier lorsqu'un redimensionnement est requis lors de l'exécution de la boucle.
Alternatives candidates
std ::vecteur avec réduction OpenMP :
Cette approche implique l'utilisation d'une réduction définie par l'utilisateur et déclarée avec #pragma omp déclare une réduction. Le code ci-dessous montre comment il peut être appliqué pour combiner des vecteurs en parallèle :
#pragma omp declare reduction (merge : std::vector<int> : omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end())) std::vector<int> vec; #pragma omp parallel for reduction(merge: vec) for (int i = 0; i < 100; i++) vec.push_back(i);
std::vector avec planification statique et insertion ordonnée :
Si la préservation de l'ordre des éléments est essentielle, cette technique peut être utilisée. Il utilise un calendrier statique et une section ordonnée pour insérer des vecteurs dans la séquence souhaitée :
std::vector<int> vec; #pragma omp parallel { std::vector<int> vec_private; #pragma omp for nowait schedule(static) for (int i = 0; i < N; i++) vec_private.push_back(i); #pragma omp for schedule(static) ordered for (int i = 0; i < omp_get_num_threads(); i++) { #pragma omp ordered vec.insert(vec.end(), vec_private.begin(), vec_private.end()); } }
Méthode de somme de préfixe :
Cette méthode évite de stocker des vecteurs pour chaque thread, en optant pour un seul vecteur fusionné en parallèle. Il exploite un tableau de somme de préfixes pour suivre les points d'insertion :
std::vector<int> vec; size_t *prefix; #pragma omp parallel { int ithread = omp_get_thread_num(); int nthreads = omp_get_num_threads(); #pragma omp single { prefix = new size_t[nthreads + 1]; prefix[0] = 0; } std::vector<int> vec_private; #pragma omp for schedule(static) nowait for (int i = 0; i < 100; i++) vec_private.push_back(i); prefix[ithread + 1] = vec_private.size(); #pragma omp barrier #pragma omp single { for (int i = 1; i < (nthreads + 1); i++) prefix[i] += prefix[i - 1]; vec.resize(vec.size() + prefix[nthreads]); } std::copy(vec_private.begin(), vec_private.end(), vec.begin() + prefix[ithread]); } delete[] prefix;
Ces alternatives fournissent des moyens efficaces et efficients de travailler avec des boucles for parallèles et de redimensionner des vecteurs dans un environnement OpenMP, dépassant les limites posé par std :: vector.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!