1. 程式人生 > >openmp在多重迴圈內的簡單使用及其詳解

openmp在多重迴圈內的簡單使用及其詳解

// 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設定每個並行塊尺寸一樣。