openmp在多重迴圈內的簡單使用及其詳解
阿新 • • 發佈:2018-12-18
// File: PrivateTest.cpp : 定義控制檯應用程式的入口點。 #include<omp.h> #include<iostream> using namespace std; //private測試 int PrivateTest() { cout<<"private輸出:\n"; inti=0,j=10; #pragmaomp parallel for private(j) for(i=0;i<8;i++) { cout<<i<<":"<<j<<"\n"; j++; cout<<i<<":"<<j<<"\n"; } return0; }
// File: PrivateTest.cpp : 定義控制檯應用程式的入口點。 #include<omp.h> #include<iostream> using namespace std; //private測試 int PrivateTest() { cout<<"private輸出:\n"; int i=0,j=10; #pragmaomp parallel for private(j) for(i=0;i<8;i++) { j=10; cout<<i<<":"<<j<<"\n"; j++; cout<<i<<":"<<j<<"\n"; } return0; }
firstprivate條件用於表示其後list列出的變數在並形體中私有的,但其在並形體中的初始化值為並行之前設定的值。同樣以上面的程式碼為例:
// File: FirstPrivateTest.cpp : 定義控制檯應用程式的入口點。 #include<omp.h> #include<iostream> using namespace std; //FirstPrivateTest測試 int FirstPrivateTest() { cout<<"firstprivate輸出:\n"; inti=0,j=10; #pragmaomp parallel for firstprivate(j) for(i=0;i<8;i++) { cout<<i<<":"<<j<<"\n"; j++; cout<<i<<":"<<j<<"\n"; } return0; }
該程式碼與之前程式碼沒有什麼太大區別,儘管在並形體中沒有對j進行初始化,但是它能正常正確的執行,其原因就是將變數j設定成了firstprivate。雖說在並形體中並沒有對j進行初始化,但是在並形體中j的初始值就是10。
lastprivate條件與firstprivate的含義類似,只是它設定的變數需要在並形體中初始化,但是其最後的結果可以在並形體外部使用。
// File: LastPrivateTest.cpp : 定義控制檯應用程式的入口點。
#include<omp.h>
#include<iostream>
using namespace std;
//LastPrivateTest測試
int LastPrivateTest()
{
cout<<"lastprivate輸出:\n";
inti=0,j=10;
#pragmaomp parallel for lastprivate(j)
for(i=0;i<8;i++)
{
j=5;
cout<<i<<":"<<j<<"\n";
j++;
cout<<i<<":"<<j<<"\n";
}
cout<<"最後j的值為:"<<j<<"\n";
return0;
}
// File: ReductionTest.cpp : 定義控制檯應用程式的入口點。
#include<omp.h>
#include<iostream>
using namespace std;
//ReductionTest測試
int ReductionTest()
{
cout<<"reduction輸出:\n";
inti=0,j=10;
#pragmaomp parallel for reduction(+:j)
for(i=0;i<8;i++)
{
j=2;
cout<<i<<":"<<j<<"\n";
j++;
cout<<i<<":"<<j<<"\n";
}
cout<<"最後j的值為:"<<j<<"\n";
return0;
}
// File: ScheduleTest.cpp
#include<omp.h>
#include<iostream>
using namespace std;
//private測試
int ScheduleTest()
{
cout<<"ScheduleTest輸出:\n";
inti=0,j,chunkSize = 1;
doublestarttime,endtime;
cout<<"請輸入並行塊的大小(-200):\n";
cin>>chunkSize;
starttime=omp_get_wtime();
#pragmaomp parallel for private(j)schedule(static,chunkSize)
for(i=0;i<200;i++)
{
for(j=0;j<100000000;j++);
}
endtime=omp_get_wtime();
cout<<"計算耗時為:"<<endtime-starttime<<"s\n";
return0;
}
從上圖以及測試結果可以得知:在每核平均執行並行塊數目大於或等於1.0時,並行塊數目對計算效率的影響呈鋸齒狀形態;當每核平均執行並行塊數目小於1.0時,計算效率急劇下降;空閒執行緒數目越多,計算效率越低。當每核平均執行並行塊數目為1,且每個並行塊中尺寸均勻相等時,計算效率會提供到極大值,上例中即並行塊尺寸為25時。若每個迴圈的計算量相差不大,建議採用static設定每個並行塊尺寸一樣。