2015-06-11 44 views
1

我是新的openMP,我嘗試優化循環。結果並不如預期,for循環無法正常工作(由於依賴性)。我不知道如何得到一個完美的並行循環與下面的例子:並行for循環與減少和操縱數組

#pragma omp parallel for default(shared) reduction(+...) 
    for(i = rest - 1; i >= 0; i--) { 
     scounts[i] += N; 
    } 

    #pragma omp parallel for private(i) 
    for(i = 1; i < p; i++) { 
     disp[i] = disp[i-1] + scounts[i-1]; 
    } 

我嘗試了這些2個編譯指令沒有任何更迭。在這些情況下進行的最佳方式是什麼?

+1

你應該比「出事了」更具體。出了什麼問題?你能指望什麼?會發生什麼呢? –

+0

@HristoIliev,我認爲很清楚爲什麼由於第二個循環中的依賴關係「出現了問題」。 –

回答

1

您已經選擇了一個困難的問題並行做。一般來說,在編寫數組時,您不希望數組的元素依賴於之前的元素,而這正是您在第二個循環中所具有的元素。

大多數人在看到依賴關係時會放棄。但這些都是需要思考的有趣案例。在你的情況下,你的第二個迴路相當於

type sum = 0; //replace type with int, float, double... 
for(i = 1; i < p; i++) { 
    sum += scounts[i-1]; 
    disp[i] = disp[0] + sum; 
} 

這是一個累積和(又名prefix sum)。 OpenMP不提供簡單的構造來完成前綴總和。你必須通過兩次。這裏是你如何做到這一點(我假設的disp類型和scountsint但你可以float更換或其他):

int *suma; 
#pragma omp parallel 
{ 
    int ithread = omp_get_thread_num(); 
    int nthreads = omp_get_num_threads(); 
    #pragma omp single 
    { 
     suma = malloc(nthreads * sizeof *suma); 
     suma[0] = 0; 
    } 
    int sum = 0; 
    #pragma omp for schedule(static) 
    for (int i=1; i<p; i++) { 
     sum += scounts[i-1]; 
     disp[i] = disp[0] + sum; 
    } 
    suma[omp_get_thread_num()+1] = sum; 
    #pragma omp barrier 
    int offset = 0; 
    for(int i=0; i<(ithread+1); i++) { 
     offset += suma[i]; 
    } 
    #pragma omp for schedule(static) 
    for(int i=1; i<p; i++) { 
     disp[i] += offset; 
    } 
} 
free(suma); 

但如果你只是學習OpenMP的,我建議你開始用更簡單案例第一。

0

請直接使用#pragma

#pragma omp parallel ... 

,而不是#pragma的評論:

// #pragma omp parallel ... 
+1

在第二個循環中實際上存在一個循環攜帶的依賴關係。 –

+1

謝謝你的回答,我對un雜注發表評論,因爲它不能並行工作。 – r0m