2012-01-31 49 views
3

我正在使用gcc的openmp實現嘗試並行化一個程序。基本上這個任務是添加omp編譯指示來獲得加速的程序,找到amicable numbersgcc openmp線程重用

給出了原始的串行程序(下面顯示的除了在最後添加了註釋的3行)。我們必須首先將外部循環,然後是內部循環。外部循環很容易,對於給定數量的處理器,我接近理想的加速比。對於內部循環,我得到比原始串行程序更糟糕的性能。基本上我試圖做的是減少總和變量。

看看CPU的使用情況,我只使用〜每核30%。什麼可能導致這個?程序每次碰到omp parallel for子句時是否不斷創建新線程?在減少障礙方面是否有更多的開銷?或者它可能是內存訪問問題(例如緩存顛簸)?從我讀的大多數openmp線程的實現中獲得重用加班(例如合併),所以我不太確定第一個問題是什麼問題。

#include<stdio.h> 
#include<stdlib.h> 
#include<math.h> 
#include <omp.h> 
#define numThread 2 
int main(int argc, char* argv[]) { 
    int ser[29], end, i, j, a, limit, als; 
    als = atoi(argv[1]); 
    limit = atoi(argv[2]); 
    for (i = 2; i < limit; i++) { 
     ser[0] = i; 
     for (a = 1; a <= als; a++) { 
      ser[a] = 1; 
      int prev = ser[a-1]; 
      if ((prev > i) || (a == 1)) { 
       end = sqrt(prev); 
       int sum = 0;//added this 
       #pragma omp parallel for reduction(+:sum) num_threads(numThread)//added this 
       for (j = 2; j <= end; j++) { 
        if (prev % j == 0) { 
         sum += j; 
         sum += prev/j; 
        } 
       } 
       ser[a] = sum + 1;//added this 
      } 
     } 
     if (ser[als] == i) { 
      printf("%d", i); 
      for (j = 1; j < als; j++) { 
       printf(", %d", ser[j]); 
      } 
      printf("\n"); 
     } 
    } 
} 
+0

這是C++。?! – jjj 2012-01-31 08:30:25

+0

@jjj對我來說看起來像C。你爲什麼認爲它是C++? – sehe 2012-01-31 08:31:35

+0

您是否在編譯命令中添加了-fopenmp? – batbaatar 2012-01-31 08:33:00

回答

7

OpenMP的thread teams被實例化在進入平行部。這意味着,確實每當內部循環開始時就重複創建線程。

爲了使螺紋的再使用,使用較大的平行部(控制組的壽命)和specificly控制parallellism用於外/內循環,像這樣:

執行時間test.exe 1 1000000已經從43S使用此修復程序(和線程數22S下降反映定義的值+ 1

PS或許說明明顯的numThreads,它不會出現的並行內環是完善的績效指標。但這可能是這個練習的重點,而我不要批評這個問題。

#include<stdio.h> 
#include<stdlib.h> 
#include<math.h> 
#include <omp.h> 

#define numThread 2 
int main(int argc, char* argv[]) { 
    int ser[29], end, i, j, a, limit, als; 
    als = atoi(argv[1]); 
    limit = atoi(argv[2]); 
#pragma omp parallel num_threads(numThread) 
    { 
#pragma omp single 
     for (i = 2; i < limit; i++) { 
      ser[0] = i; 
      for (a = 1; a <= als; a++) { 
       ser[a] = 1; 
       int prev = ser[a-1]; 
       if ((prev > i) || (a == 1)) { 
        end = sqrt(prev); 
        int sum = 0;//added this 
#pragma omp parallel for reduction(+:sum) //added this 
        for (j = 2; j <= end; j++) { 
         if (prev % j == 0) { 
          sum += j; 
          sum += prev/j; 
         } 
        } 
        ser[a] = sum + 1;//added this 
       } 
      } 
      if (ser[als] == i) { 
       printf("%d", i); 
       for (j = 1; j < als; j++) { 
        printf(", %d", ser[j]); 
       } 
       printf("\n"); 
      } 
     } 
    } 
} 
+0

你是親。有時間閱讀線程團隊。 – 2012-01-31 09:24:18

+0

@JamesCotter:歡呼聲並保持它! – sehe 2012-01-31 09:28:16

+0

嗯等待一秒......運行串行程序在3秒鐘內完成,而線程完成在15秒的參數2 1000000. – 2012-01-31 09:30:54