J'ai le code C/C++ suivant en utilisant OpenMP:
int nProcessors=omp_get_max_threads();
if(argv[4]!=NULL){
printf("argv[4]: %s\n",argv[4]);
nProcessors=atoi(argv[4]);
printf("nProcessors: %d\n",nProcessors);
}
omp_set_num_threads(nProcessors);
printf("omp_get_num_threads(): %d\n",omp_get_num_threads());
exit(0);
Comme vous pouvez le constater, j'essaie de définir le nombre de processeurs à utiliser en fonction d'un argument transmis sur la ligne de commande.
Cependant, je reçois le résultat suivant:
argv[4]: 2 //OK
nProcessors: 2 //OK
omp_get_num_threads(): 1 //WTF?!
Pourquoi omp_get_num_threads()
ne retourne-t-il pas 2? !!!
Comme on l'a fait remarquer, j'appelle omp_get_num_threads()
dans une région série. Par conséquent, la fonction renvoie 1
.
Cependant, j'ai le code parallèle suivant:
#pragma omp parallel for private(i,j,tid,_hash) firstprivate(firstTime) reduction(+:nChunksDetected)
for(i=0;i<fileLen-CHUNKSIZE;i++){
tid=omp_get_thread_num();
printf("%d\n",tid);
int nThreads=omp_get_num_threads();
printf("%d\n",nThreads);
...
qui produit:
0 //tid
1 //nThreads - this should be 2!
0
1
0
1
0
1
...
L'appel omp_get_num_threads()
renvoie 1 dans la section série du code. Voir Lien
Vous devez donc avoir un code parallèle pour obtenir la valeur correcte, voici comment votre code devrait ressembler à ceci:
#include <iostream>
#include <omp.h>
int main (int argc, const char * argv[])
{
int nProcessors = omp_get_max_threads();
std::cout<<nProcessors<<std::endl;
omp_set_num_threads(nProcessors);
std::cout<<omp_get_num_threads()<<std::endl;
#pragma omp parallel for
for(int i = 0; i < 5; i++){
int tid = omp_get_thread_num();
std::cout<<tid<<"\t tid"<<std::endl;
int nThreads = omp_get_num_threads();
std::cout<<nThreads<<"\t nThreads"<<std::endl;
}
exit(0);
}
Ce code produit:
2
1
0 tid
2 nThreads
0 tid
2 nThreads
0 tid
2 nThreads
1 tid
2 nThreads
1 tid
2 nThreads
Il semble que vous avez soit mp ouvert non activé, soit votre boucle n’est pas sous la forme qui peut être mise en parallèle par openmp
vous utilisez la mauvaise fonction. utilisez omp_get_max_threads
pour vérifier le nombre maximal de threads autorisés.
Il a déjà été signalé que omp_get_num_threads()
renvoie 1
dans des sections séquentielles du code. En conséquence, même si vous définissez, par omp_set_num_threads()
, un nombre total de threads supérieur à 1
, tout appel à omp_get_num_threads()
renverra 1
, sauf si nous sommes dans une section parallèle. L'exemple ci-dessous tente de clarifier ce point
#include <stdio.h>
#include <omp.h>
int main() {
const int maxNumThreads = omp_get_max_threads();
printf("Maximum number of threads for this machine: %i\n", maxNumThreads);
printf("Not yet started a parallel Section: the number of threads is %i\n", omp_get_num_threads());
printf("Setting the maximum number of threads...\n");
omp_set_num_threads(maxNumThreads);
printf("Once again, not yet started a parallel Section: the number of threads is still %i\n", omp_get_num_threads());
printf("Starting a parallel Section...\n");
#pragma omp parallel for
for (int i = 0; i < maxNumThreads; i++) {
int tid = omp_get_thread_num();
printf("This is thread %i announcing that the number of launched threads is %i\n", tid, omp_get_num_threads());
}
}