2009-09-19 71 views
74

的是這兩者之間的區別?OMP並行與OMP並行的

[A]

#pragma omp parallel 
{ 
    #pragma omp for 
    for(int i = 1; i < 100; ++i) 
    { 
     ... 
    } 
} 

[B]

#pragma omp parallel for 
for(int i = 1; i < 100; ++i) 
{ 
    ... 
} 

回答

50

我不認爲有任何差異,一個是爲其他的快捷方式。儘管你的確切實現可能會以不同的方式處理

將合併的並行工作共享構建體是用於 快捷方式指定包含一個工作共享構造 並行構造和其它語句。允許的條款是允許並行和工作共享contructs條款 的工會。

http://www.openmp.org/mp-documents/OpenMP3.0-SummarySpec.pdf

採取表示OpenMP的規格在這裏:

http://openmp.org/wp/openmp-specifications/

44

這些是等價的。

#pragma omp parallel產生了一組線程,而#pragma omp for劃分了產生的線程之間的循環迭代。您可以使用融合的#pragma omp parallel for指令一次完成這兩件事。

+0

在我的代碼中,我正在使用這個結構。但是,當我在for指令中使用'schedule(static,chunk)'子句時,我遇到了一個問題。代碼運行良好,但是當我從MPI程序調用此代碼時,它會運行到無限循環。循環計數器在此循環的所有迭代中都爲零。我在'#pragma omp parallel'指令中將循環計數器定義爲private。不知道爲什麼它只在MPI調用代碼時失敗。我確信每個MPI進程都在羣集的不同處理器上運行(如果有的話)。不知道日程安排是否會導致問題。 – 2011-10-03 02:29:03

+0

當我使用'#pragma omp parallel for'指令時,同樣的事情可以正常工作。應該有一些區別。 – 2011-10-03 02:30:16

+1

更新:事實證明,我只在使用schedule子句時才觀察到這個問題,所以我猜這不取決於我是使用組合並行還是兩個不同的指令。 – 2011-10-03 19:52:07

2

我看到截然不同的運行時,當我採取一個for循環以g ++ 4.7.0 和使用

std::vector<double> x; 
std::vector<double> y; 
std::vector<double> prod; 

for (int i = 0; i < 5000000; i++) 
{ 
    double r1 = ((double)rand()/double(RAND_MAX)) * 5; 
    double r2 = ((double)rand()/double(RAND_MAX)) * 5; 
    x.push_back(r1); 
    y.push_back(r2); 
} 

int sz = x.size(); 

#pragma omp parallel for 

for (int i = 0; i< sz; i++) 
    prod[i] = x[i] * y[i]; 

串行代碼(沒有openmp)運行在79毫秒。 「並行」代碼在29 ms內運行。 如果我省略了for和使用#pragma omp parallel,運行時拍攝到179ms, 比串行代碼慢。 (本機具有的8 HW併發)

代碼鏈接到libgomp

+2

我認爲這是因爲omp parallel在單獨的線程中執行循環而沒有將其分成線程,所以主線程正在等待第二個線程完成。並花費在同步上。 – Antigluk 2012-10-24 15:38:08

+6

這是因爲沒有'#pragma omp for',根本沒有多線程共享循環。但是,這不是OPs的情況,請在'#pragm omp parallel'內再次使用'#pragma omp for'來嘗試再次運行,它應該像'#pragma omp parallel for'版本一樣運行(如果不是相同的話) 。 – 2013-10-14 15:27:36

+0

我認爲這個答案是最好的答案,因爲它表明它們不是「等價的」 – 2017-03-25 09:45:33

19

下面是實施例的使用分離parallelforhere。簡而言之,它可用於在幾個線程中執行for週期之前動態分配OpenMP線程專用陣列。 這是不可能做同樣的初始化中parallel for情況。

UPD: 在問題例如有單個編譯和兩個編譯指示之間無差異。但在實踐中,您可以使用分離的並行和指令使線程感知更多的行爲。 例如有些代碼:

#pragma omp parallel 
{ 
    double *data = (double*)malloc(...); // this data is thread private 

    #pragma omp for 
    for(1...100) // first parallelized cycle 
    { 
    } 

    #pragma omp single 
    {} // make some single thread processing 

    #pragma omp for // second parallelized cycle 
    for(1...100) 
    { 
    } 

    #pragma omp single 
    {} // make some single thread processing again 

    free(data); // free thread private data 
} 
4

雖然具體例子的兩個版本是等價的,在其他的答案已經提到的,它們之間還是一個小的差異。第一個版本包含一個不必要的隱含屏障,在「omp for」結尾處遇到。另一個隱式屏障可以在並行區域的末尾找到。將「nowait」添加到「omp for」會使兩個代碼等效,至少從OpenMP的角度來看。我提到這是因爲OpenMP編譯器可能會爲這兩種情況生成稍微不同的代碼。