簡體   English   中英

如何並行化多CPU的c程序

[英]how to parallelize the c-program for multi CPU

結果通常看起來是錯誤的,因為並行化后的 'bmmin' 似乎是錯誤的或類似的東西..

    #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];
      };
    };
    };

運行代碼時,輸出如下:

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

在很多情況下 bmmin=2.96034e-05,甚至 r 值也有很大的變化。

bmmin結果在許多線程中看起來幾乎相同,為什么?

這是因為它在代碼的並行部分被定義為private變量。 事實上,同樣的事情適用於thread_id和其他變量,如r 私有變量是一個定義的變量,只能從每個線程訪問。 如果你想讓主線程訪問每個線程的結果,那么你需要將值存儲在一個數組中。 或者,您可以使用OpenMP 縮減

[...] 看起來 'i' 值超出了 for 循環的范圍

默認情況下,變量在並行部分中隱式共享 這意味着i默認是共享的。 因此, i上存在競爭條件 您需要將其設為私有或在並行部分中聲明它,以便每個線程都有自己的版本。

請注意, omp parallel部分共享線程之間的工作。 您需要使用parallel for或自己完成(例如,拆分nel以便每個線程計算循環的一部分,如果這是您想要的)。

除此之外, #pragma omp critical在並行部分之外什么也不做。 使用兩個指令可能會有用: #pragma omp for指令到#pragma omp parallel#pragma omp for ones。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM