Maison >développement back-end >C++ >Comment effectuer efficacement des réductions de tableau dans OpenMP ?

Comment effectuer efficacement des réductions de tableau dans OpenMP ?

Susan Sarandon
Susan Sarandonoriginal
2024-12-03 09:07:121008parcourir

How to Efficiently Perform Array Reductions in OpenMP?

Résoudre les réductions de tableaux dans OpenMP

Dans OpenMP, la réduction directe sur les tableaux n'est pas prise en charge. Cependant, des méthodes alternatives existent pour obtenir des résultats similaires.

Première méthode :

Une approche consiste à créer des copies privées du tableau pour chaque thread et à les réduire localement. Après la section parallèle, fusionnez les tableaux privés dans le tableau d'origine en utilisant une section critique pour éviter les courses de données.

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 :

Une autre méthode consiste à allouez un tableau plus grand avec des dimensions égales à la taille du tableau multipliée par le nombre de threads. Chaque thread remplit ensuite sa partie du tableau. Après la section parallèle, fusionnez les valeurs dans le tableau d'origine sans utiliser de section critique.

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];
        }
    }
}

La deuxième méthode est plus efficace, en particulier dans les scénarios impliquant plusieurs sockets, mais elle nécessite également une gestion minutieuse de la mémoire pour éviter problèmes de cache.

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