web-dev-qa-db-fra.com

OpenMP set_num_threads () ne fonctionne pas

J'écris un programme parallèle en utilisant OpenMP en C++.

Je veux contrôler le nombre de threads dans le programme en utilisant omp_set_num_threads(), mais cela ne fonctionne pas.

#include <iostream>
#include <omp.h>
#include "mpi.h"

using namespace std;

int myrank;
int groupsize;
double sum;
double t1,t2;
int n = 10000000;

int main(int argc, char *argv[])
{
    MPI_Init( &argc, &argv);
    MPI_Comm_rank( MPI_COMM_WORLD, &myrank );
    MPI_Comm_size(MPI_COMM_WORLD,&groupsize);

    omp_set_num_threads(4);

    sum = 0;
    #pragma omp for  reduction(+:sum)
    for (int i = 0; i < n; i++)
        sum+= i/(n/10);

    cout<<"sum="<<sum<<endl;
    cout<<"threads="<<omp_get_num_threads()<<endl;

    MPI_Finalize();
    return 0;
}

Le programme génère:

sum = 4.5e+007
threads=1

Comment contrôler le nombre de threads?

24
Nurlan

À part appeler omp_get_num_threads() en dehors de la région parallèle dans votre cas, appeler omp_set_num_threads() ne garantit toujours pas que le runtime OpenMP utilisera exactement le nombre de threads spécifié. omp_set_num_threads() est utilisé pour remplacer la valeur de la variable d'environnement OMP_NUM_THREADS et ils contrôlent tous les deux la limite supérieure de la taille de l'équipe de threads générés par OpenMP pour toutes les régions parallèles (dans le cas de OMP_NUM_THREADS) ou pour tout parallèle ultérieur région (après un appel à omp_set_num_threads()). Il existe quelque chose appelé équipes dynamiques qui peuvent toujours choisir un nombre plus faible de threads si le système d'exécution le juge plus approprié. Vous pouvez désactiver les équipes dynamiques en appelant omp_set_dynamic(0) ou en définissant la variable d'environnement OMP_DYNAMIC sur false.

Pour appliquer un nombre donné de threads, vous devez désactiver les équipes dynamiques et spécifier le nombre souhaité de threads avec l'un des éléments omp_set_num_threads():

omp_set_dynamic(0);     // Explicitly disable dynamic teams
omp_set_num_threads(4); // Use 4 threads for all consecutive parallel regions
#pragma omp parallel ...
{
    ... 4 threads used here ...
}

ou avec la clause Opencode num_threads:

omp_set_dynamic(0);     // Explicitly disable dynamic teams
// Spawn 4 threads for this parallel region only
#pragma omp parallel ... num_threads(4)
{
    ... 4 threads used here ...
}
77
Hristo Iliev

La fonction omp_get_num_threads() renvoie le nombre de threads qui sont actuellement dans l'équipe exécutant la région parallèle à partir de laquelle elle est appelée. Vous l'appelez en dehors de la région parallèle, c'est pourquoi il renvoie 1.

16
Smi

Selon le manuel GCC pour omp_get_num_threads :

Dans une section séquentielle du programme, omp_get_num_threads renvoie 1

Donc ça:

cout<<"sum="<<sum<<endl;
cout<<"threads="<<omp_get_num_threads()<<endl;

Devrait être changé en quelque chose comme:

#pragma omp parallel
{
    cout<<"sum="<<sum<<endl;
    cout<<"threads="<<omp_get_num_threads()<<endl;
}

Le code que j'utilise est conforme aux conseils de Hristo concernant la désactivation des équipes dynamiques.

4
jww

Je faisais face au même problème. La solution est donnée ci-dessous 

Cliquez avec le bouton droit de la souris sur Programme source> Propriétés> Propriétés de configuration> C/C++> Langue> Modifiez maintenant l'indicateur de prise en charge Ouvrir MP sur Oui .... 

Vous obtiendrez le résultat souhaité.

2
Ali Jafar

Essayez de placer votre num_threads dans votre code parallèle omp, cela a fonctionné pour moi . Cela donnera une sortie en 4

#pragma omp parallel
{
   omp_set_num_threads(4);
   int id = omp_get_num_threads();
   #pragma omp for
   for (i = 0:n){foo(A);}
}

printf("Number of threads: %d", id);
0
Yokesh