Ich lerne OpenMP und C und habe einige Probleme mit einfachen Programmen.OpenMP mit C und gcc omp_set_num_threads() hat keinen Effekt
Ich habe die folgenden Umgebungsvariablen in meinem bashrc gesetzt:
define how many threads you want
export OMP_NUM_THREADS=4
#allow to switch number of threads
export OMP_DYNAMIC=true
#allow nested parallel regions
export OMP_NESTED=true
Hier ist das Programm, das ich zu laufen bin versucht:
#include <stdio.h> /* input, output */
#include <omp.h> /* openMP library */
#include <time.h> /* measure time */
#define N 100000000 // if sourcearray not static, I'll be overflowing the stack.
// > ~10^6 elements is a lot for most systems.
void forloop(void);
int
main(void)
{
/* worksharing: for loop */
forloop();
return(0);
}
/*=============================================================*/
/*=============================================================*/
void forloop(void){
/*do a for loop sequentially and in parallel; measure each times */
printf("=====================\n");
printf("FOR LOOP\n");
printf("=====================\n\n");
long i;
clock_t start, end;
double cpu_time_used;
static double sourcearray[N];
/*============*/
/*measure time*/
/*============*/
start=clock();
for (i=0; i<N; i++){
sourcearray[i] = ((double) (i)) * ((double) (i))/2.2034872;
}
end = clock();
cpu_time_used = ((double) (end - start))/CLOCKS_PER_SEC;
printf("Non-parallel needed %lf s\n", cpu_time_used);
/*===============*/
/*parallel region*/
/*===============*/
#pragma omp parallel
/*need to specify num_threads, when OMP_DYNAMIC=true to make sure 4 are used.*/
{
omp_set_num_threads(4);
double starttime_omp, endtime_omp;
/*time measurement*/
starttime_omp=omp_get_wtime();
int procs, maxt, nt, id;
procs = omp_get_num_procs(); // number of processors in use
maxt = omp_get_max_threads(); // max available threads
nt = omp_get_num_threads();
id = omp_get_thread_num();
printf("num threads forloop %d from id %d, procs: %d, maxthrds: %d\n", nt, id, procs, maxt);
#pragma omp for
for (i=0; i<N; i++){
sourcearray[i] = ((double) (i)) * ((double) (i))/2.2034872;
}
endtime_omp = omp_get_wtime();
cpu_time_used = ((endtime_omp - starttime_omp)) ;
} /* end parallel region */
}
ich den Code mit gcc -g kompilieren - Wall -fopenemp -o omp_worksharing.exe omp_worksharing.c
Das Programm kompiliert mit einer Warnung, die ich nicht ganz verstehe:
omp_worksharing.c: In function ‘forloop’:
omp_worksharing.c:78:17: warning: variable ‘sourcearray’ set but not used [-Wunused-but-set-variable]
static double sourcearray[N];
aber das ist nicht das Hauptproblem:
Das Problem ist, dass das Programm nicht 4 Threads beginnt. Dies ist die Ausgabe:
=====================
FOR LOOP
=====================
Non-parallel needed 0.900340 s
num threads forloop 3 from id 0, procs: 8, maxthrds: 4
num threads forloop 3 from id 1, procs: 8, maxthrds: 4
num threads forloop 3 from id 2, procs: 8, maxthrds: 4
Gleiche passiert, wenn ich #pragma omp num_threads(4)
statt omp_set_num_threads(4);
noch seltsamer, ich, wenn ich beide #pragma omp num_threads(4)
auslassen und omp_set_num_threads(4);
die meisten der Zeit 3 Threads gestartet werden, aber manchmal 4. Ich konnte keine Regelmäßigkeit finden, wenn oder warum, aber eine Untersuchung legt nahe, dass die OMP_DYNAMIC=true
OpenMP die Anzahl der Threads selbst optimal auswählen kann.
Wie kann ich die Anzahl der zu verwendenden Threads nicht angeben?
Das hat tatsächlich funktioniert, danke! Irgendeine Idee warum '#pragma omp num_threads (4)' nicht? Liegt es am 'OMP_DYNAMIC = true'? Oder warum ich die unbenutzte variable Warnung bekomme? – lemdan
Haben Sie versucht, es auch '#pragma omp parallel 'zu platzieren? –
Das hat tatsächlich funktioniert. Es scheint mir seltsam, wie die meisten Tutorials es in der gleichen Zeile tun ... Zuletzt, haben Sie irgendwelche Informationen darüber, warum ich die ungenutzte Variable Warnung bekomme? Ich benutze eindeutig das Array, auch im sequentiellen Teil. – lemdan