Maison >développement back-end >C++ >Comment la réduction de tableau peut-elle être parallélisée dans OpenMP ?

Comment la réduction de tableau peut-elle être parallélisée dans OpenMP ?

Susan Sarandon
Susan Sarandonoriginal
2024-12-07 03:13:10887parcourir

How Can Array Reduction be Parallelized in OpenMP?

Réduction sur un tableau en OpenMP

Il n'est pas possible d'effectuer directement une réduction sur un tableau en OpenMP. Cependant, il existe des approches alternatives pour obtenir le parallélisme de réduction de tableau.

Première méthode : tableaux privés et section critique

Cette méthode crée des copies privées du tableau pour chaque thread. Chaque thread remplit son tableau privé et une section critique est utilisée pour fusionner les résultats dans le tableau final.

int A[] = {84, 30, 95, 94, 36, 73, 52, 23, 2, 13};
int S[10] = {0};

#pragma omp parallel
{
    int S_private[10] = {0};
    
    #pragma omp for
    for (int n = 0; n < 10; ++n) {
        for (int m = 0; m <= n; ++m) {
            S_private[n] += A[m];
        }
    }
    
    #pragma omp critical
    {
        for(int n = 0; n < 10; ++n) {
            S[n] += S_private[n];
        }
    }
}

Deuxième méthode : expansion du tableau et accumulation indépendante des threads

Cette méthode crée un tableau étendu qui couvre tous les threads. Chaque thread remplit sa partie du tableau, puis les résultats sont fusionnés sans utiliser de section critique. Cette approche peut poser des problèmes de cache si elle n'est pas utilisée avec précaution sur des systèmes multi-sockets.

int A[] = {84, 30, 95, 94, 36, 73, 52, 23, 2, 13};
int S[10] = {0};
int *S_private;

#pragma omp parallel
{
    const int nthreads = omp_get_num_threads();
    const int ithread = omp_get_thread_num();

    #pragma omp single 
    {
        S_private = new int[10 * nthreads];
        for(int i = 0; i < (10 * nthreads); i++) S_private[i] = 0;
    }
    #pragma omp for
    for (int n = 0; n < 10; ++n)
    {
        for (int m = 0; m <= n; ++m){
            S_private[ithread * 10 + n] += A[m];
        }
    }
    #pragma omp for
    for(int i = 0; i < 10; i++) {
        for(int t = 0; t < nthreads; t++) {
            S[i] += S_private[10 * t + i];
        }
    }
}
delete[] S_private;

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn