Maison >développement back-end >C++ >Quelles sont les meilleures alternatives à « std :: vector » dans les boucles For parallèles OpenMP ?

Quelles sont les meilleures alternatives à « std :: vector » dans les boucles For parallèles OpenMP ?

Susan Sarandon
Susan Sarandonoriginal
2024-12-05 12:30:11798parcourir

What are the Best Alternatives to `std::vector` in OpenMP Parallel For Loops?

Boucle For parallèle C OpenMP : alternatives à std::vector

Les boucles for parallèles d'OpenMP offrent un moyen pratique de paralléliser le code. Cependant, l’utilisation de structures de données partagées au sein de ces boucles peut introduire des goulots d’étranglement en termes de performances. Une structure de données couramment utilisée, std::vector, n'est peut-être pas le meilleur choix pour une utilisation partagée dans des boucles parallèles.

Alternatives à std::vector🎜>

Pour performances optimales et sécurité des threads en parallèle pour les boucles, considérez ces alternatives à std::vector:

std::vector avec Réductions définies par l'utilisateur

OpenMP 4.0 introduit des réductions définies par l'utilisateur, vous permettant de définir des opérations de réduction personnalisées pour des structures de données personnalisées. Cette approche peut améliorer les performances en évitant la surcharge liée au verrouillage des données partagées.

Exemple :

#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);

Vecteur ordonné

Si l'ordre des éléments dans le vecteur partagé est crucial, considérez ce qui suit approche :

std::vector<int> vec;
#pragma omp parallel
{
    std::vector<int> vec_private;
    #pragma omp for schedule(static) nowait
    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());
    }
}

Classe de vecteurs parallèles personnalisés

Pour les structures de données partagées complexes, vous devrez peut-être implémenter des classes de vecteurs parallèles personnalisées pour gérer le redimensionnement pendant la boucle tout en garantissant sécurité des fils et performances efficaces.

Exemple :

class ParallelVector {
private:
    std::vector<int> data;
    std::atomic<size_t> size;

public:
    void push_back(int value) {
        size++;
        data.push_back(value);
    }

    size_t getSize() {
        return size.load();
    }
};

ParallelVector vec;

#pragma omp parallel
{
    #pragma omp for
    for (int i = 0; i < 100; i++) vec.push_back(i);
}
Le choix L'alternative à std::vector dépend des exigences spécifiques de votre boucle parallèle. Tenez compte de facteurs tels que la sécurité des threads, les performances et la facilité de mise en œuvre pour sélectionner la solution la plus appropriée pour votre application.

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