2014-02-08 123 views
0

這是OpenMP的網站上練習: https://computing.llnl.gov/tutorials/openMP/exercise.htmlOpenMP的鍛鍊omp_bug2.c


#include "stdafx.h" 
#include <omp.h> 
#include <stdio.h> 
#include <stdlib.h> 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
int nthreads, i, tid; 
float total; 

/*** Spawn parallel region ***/ 
#pragma omp parallel private(i, tid) // i changed this line 
    { 
    /* Obtain thread number */ 
    tid = omp_get_thread_num(); 
    /* Only master thread does this */ 
    if (tid == 0) { 
    nthreads = omp_get_num_threads(); 
    printf("Number of threads = %d\n", nthreads); 
    } 
    printf("Thread %d is starting...\n",tid); 

    #pragma omp barrier 

    /* do some work */ 
    total = 0.0; 
    #pragma omp for schedule(dynamic,10) 
    for (i=0; i<1000000; i++) 
    total = total + i*1.0; 

    printf ("Thread %d is done! Total= %e\n",tid,total); 

    } 
} 

的輸出,這是

Number of threads = 4 
Thread 0 is starting... 
Thread 3 is starting... 
Thread 2 is starting... 
Thread 1 is starting... 
Thread 0 is done! Total= 0.000000e+000 
Thread 3 is done! Total= 0.000000e+000 
Thread 2 is done! Total= 0.000000e+000 
Thread 1 is done! Total= 0.000000e+000 

這意味着我們有一個問題可變「總」

這是對網站的幫助enter image description here

這是我的解決方案:你認爲這是正確的方法嗎?

#include "stdafx.h" 
#include <omp.h> 
#include <stdio.h> 
#include <stdlib.h> 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
int nthreads, i, tid; 
float total; 

/*** Spawn parallel region ***/ 
#pragma omp parallel private(total,tid) 
    { 
    /* Obtain thread number */ 
    tid = omp_get_thread_num(); 
    total= 0.0; 
    /* Only master thread does this */ 
    if (tid == 0) { 
    nthreads = omp_get_num_threads(); 
    printf("Number of threads = %d\n", nthreads); 
    } 
    printf("Thread %d is starting...\n",tid); 



    #pragma omp parallel for schedule(static,10)\ 
    private(i)\ 
    reduction(+:total) 
    for (i=0; i<1000000; i++) 
    total = total + i*1.0; 

    printf ("Thread %d is done! Total= %e\n",tid,total); 

    } /*** End of parallel region ***/ 
} 

這是我的新的輸出:

Number of threads = 4 
Thread 0 is starting... 
Thread 1 is starting... 
Thread 0 is done! Total= 4.999404e+011 
Thread 2 is starting... 
Thread 1 is done! Total= 4.999404e+011 
Thread 2 is done! Total= 4.999404e+011 
Thread 3 is starting... 
Thread 3 is done! Total= 4.999404e+011 

回答

1

是你一定要total是一個線程私有變量。有一件事你可能會在一個真實的例子做的就是減少線程專用totals在結束一個單一的全球總(和只讓一個線程打印出結果,然後)。一種方法是簡單的

#pragma omp atomic 
global_total += total 

在最後(有更好的方法,雖然使用減少)。

PS:循環計數器omp for默認都是私有的,所以你其實並不需要明確指定。

+0

你可以看看我的編輯?這是你想到的嗎? – Gilad

+0

使用'reduction'是慣用的方法(儘管用私有變量和原子添加來編寫簡單版本只是爲了瞭解它在後臺如何工作是很有用的)。但是,在這種情況下,你不應該使用私有,它應該被共享。 – Voo

+0

爲什麼你認爲總共應該分享而不是私人? – Gilad