简体   繁体   中英

how to parallelize the c-program for multi CPU

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM