The result often times looks wrong, because the 'bmmin' after the parallelization seems to be wrong or something like that..
#pragma omp parallel private(thread_id, bmmin, r ,t, am, b, bm)
{
thread_id=omp_get_thread_num();
bmmin=INFINITY;
for (i=0; i<nel; i++) {
am=a[i]+ldigitse*j;
b=roundl((lval-am)/ldigits0);
bm=fabsl(am+b*ldigits0-lval);
if (bm<bmmin) {
bmmin=bm;
t[0]=(int)b;
r=ldigits[0]*t[0];
for (l=1; l<ndig; l++) {
t[l]=(*s)[i][l-1];
r=r+ldigits[l]*t[l];
};
t[ndig]=j;
r=r+ldigits[ndig]*t[ndig];
};
};
// bmmin result looks almost same in many threads, why?
printf("Thread %d: r=%Lg, bmmin=%Lg, bmmin_glob=%Lg\n",thread_id,powl(10,r),bmmin,bmmin_glob);
#pragma omp critical
if (bmmin<bmmin_glob) {
printf("Thread %d - giving minimum r=%9Lg!\n",thread_id,powl(10,r));
bmmin_glob=bmmin;
r_glob=r;
for (i=0; i<=ndig; i++) {
t_glob[i]=t[i];
};
};
};
When running the code, it outputs as:
Initializing the table of the logarithmic constants...
Calculation started for k from 0 to 38...
j,k=-19,0
Thread 7: r=2.57008e+30, bmmin=2.96034e-05, bmmin_glob=inf
Thread 7 - giving minimum r=2.57008e+30!
Thread 1: r=3.74482e+16, bmmin=2.96034e-05, bmmin_glob=inf
Thread 6: r=3.74482e+16, bmmin=2.96034e-05, bmmin_glob=inf
Thread 3: r=3.1399, bmmin=0.000234018, bmmin_glob=inf
Thread 2: r=3.74482e+16, bmmin=2.96034e-05, bmmin_glob=inf
Thread 5: r=3.1399, bmmin=0.000234018, bmmin_glob=inf
Thread 4: r=392.801, bmmin=0.000113243, bmmin_glob=inf
Thread 0: r=3.14138, bmmin=2.96034e-05, bmmin_glob=2.96034e-05
Result: 2.57008e+30
Exponents: 2^129*3^-13*5^16*7^-19
j,k=-18,1
with a lot of case that have bmmin=2.96034e-05, even the r-value has a lot of variation.
bmmin
result looks almost same in many threads, why?
This is because it is defined as a private
variable in the parallel section in the code. In fact the same thing applies for thread_id
and other variables like r
. A private variable is a variable defined and accessible only from each thread. If you want to make accessible the result of each thread to the main thread, then you need to store the value in an array. Alternatively you can use OpenMP reductions .
[...] looks like the 'i' values are out of the range of the for loop
Variable are implicitly shared by default in parallel sections. This means i
is shared by default. Thus, there is a race condition on i
. You need to put it private or to declare it inside the parallel section so each thread have its own version.
Note that omp parallel
section does not share the work between threads. You need to either use a parallel for
or to do it yourself (eg. splitting nel
so each thread compute a part of the loop if this is what you want).
Besides this, #pragma omp critical
does nothing outside a parallel section. It might be useful to use two directives: a #pragma omp for
directive to a #pragma omp parallel
and a #pragma omp for
ones.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.