C OpenMP Parallel For Loop : Alternatives à std::vector
std::vector est une structure de données polyvalente couramment utilisée en parallèle pour boucles avec OpenMP. Cependant, il existe des situations dans lesquelles des alternatives pourraient être plus adaptées, en particulier lorsque vous donnez la priorité à la vitesse ou que vous rencontrez des problèmes de redimensionnement pendant la boucle.
Une option pour une structure de données partagée consiste à utiliser une réduction personnalisée avec OpenMP 4.0. 's #pragma omp déclare une réduction. Cela réduit le besoin de sections critiques et simplifie le code parallèle.
Une autre alternative pour préserver l'ordre consiste à utiliser une planification statique avec des sections ordonnées. Cela garantit que chaque thread écrit dans une partie spécifique du vecteur dans l'ordre, éliminant ainsi le besoin de fusionner ultérieurement.
Dans les scénarios où le redimensionnement est nécessaire, une méthode utilisant des tableaux de pointeurs pour suivre le thread -des sommes de préfixes spécifiques peuvent être adoptées. Cette approche évite la surcharge liée au redimensionnement sur le chemin critique.
Voici des exemples de code pour ces alternatives :
// Custom reduction #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);
// Static scheduling with ordered sections std::vector<int> vec; #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;
La sélection de l'alternative appropriée pour votre cas spécifique dépend des exigences. et les considérations de performances. L'expérimentation et le profilage peuvent aider à déterminer la solution la plus optimale.
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!