OpenMP並行程序設計之OpenMP使用入門

OpenMP並行程序設計之OpenMP使用入門

   程序運行速度慢應該是所有程序員都特別頭疼的一個問題,當前對於程序運行加速有兩種方式:一種是通過硬件的方式加速,比如我們常聽說的硬解碼,軟解碼,這裏的硬解碼就是通過硬件對程序進行加速;一種是通過軟件的方式進行加速,而這種方式使用比較多的是使用共享存儲編程。當前對於共享存儲編程有三種標準:Pthreads,X3H5,OpenMP(最流行)。

   OpenMP是一個支持共享存儲並行設計的庫,特別適宜多核CPU上的並行程序設計,由一系列編譯指導語句和庫函數組成,說白了就是一個開源庫,和OpenCV差不多,只不過一個做並行處理庫,一個是計算機視覺庫。

   一、fork/join並行執行模式

   OpenMP使用的fork/join並行執行模式。


   OpenMP並行執行的程序要執行完並行執行區域後才能執行主線程。這就是標準的並行模式fork/join式並行模式。因此,標準並行模式執行代碼的基本思想是,程序開始時只有一個主線程,程序中的串行部分都由主線程執行,並行的部分是通過派生其他線程來執行,關閉並行區域前,主線程等待其他線程到達,也就是說,如果並行部分沒有結束時是不會執行串行部分的。(實際上,這個“等待”就是一次“隱式同步”)。

   二、如何應用OpenMP?

   1. OpenMP常用於循環並行化; 找出最耗時的循環,在串行程序上加上編譯指導語句實現並行處理,當然咯,只要每次循環互不相干,互不影響才能做成並行。

   2. OpenMP常用於互不相關的兩端或多端代碼塊的並行執行;比如在疲勞檢測中要視線眨眼檢測和哈欠檢測,那麼這個眨眼檢測和哈欠檢測就可以做成並行處理。

   三、OpenMP程序結構

   據我所知,當前OpenMP支持C、C++和fortran語言,下面就簡單的寫一個基於C/C++語言的OpenMP程序的結構。

#include<omp.h>
int  main(int argc, char *argv)
{
#pragma omp parallel
	{
		printf("i like c++ programming!\n");
	}
	
	system("pause");
	return 0;
}
   程序運行結果如下:


   可以看得出parallel語句中的代碼被執行了八次,說明總共創建了8個線程去執行parallel語句中的代碼,這個創建多少個線程與CPU的核數有關,我的電腦是八核的,所以創建了8個線程,代碼被執行了八次。

   四、並行執行特點

   在瞭解OpenMP並行執行的特點前先看個OpenMP小程序。

#include <iostream>  
#include<omp.h>
int  main(int argc, char *argv)
{
	
	printf("串行打印:\n");
	for (int i = 0; i < 10; i++)
		printf("%d, ", i);
	printf("\n");
	printf("並行打印:\n");
#pragma omp parallel for
	for (int i = 0; i < 10; i++)
		printf("%d, ", i);
	printf("\n");
	system("pause");
	return 0;
}
程序運行結果

   可見for 循環語句中的內容被並行執行了。(每次運行的打印結果可能會有區別)。這裏要說明一下,#pragma omp parallel for 這條語句是用來指定後面的for循環語句變成並行執行的,這算是是OpenMP語句入門級的使用,也是使用最頻繁的一條語句。當然咯,for循環裏的內容必須滿足可以並行執行,即每次循環互不相干,後一次循環不依賴於前面的循環。

   五、並行執行效率

   將for循環裏的語句變成並行執行後效率會不會提高呢,我想這是我們最關心的內容了。下面就寫一個簡單的測試程序來測試一下:

#include<time.h>
#include<iostream>
#include<omp.h>
void test()
{
	int a = 0;
	clock_t t1 = clock();
	for (int i = 0; i < 100000000; i++)
	{
		a = i + 1;
	}
	clock_t t2 = clock();
	printf("Time = %d\n", t2 - t1);
}

int main(int argc, char* argv[])
{
	clock_t t1 = clock();
#pragma omp parallel for
	for (int j = 0; j < 2; j++){
		test();
	}
	clock_t t2 = clock();
	printf("Total time = %d\n", t2 - t1);

	test();
	return 0;
}

   在test()函數中,執行了1億次循環,主要是用來執行一個長時間的操作。在main()函數裏,先在一個循環裏調用test()函數,只循環2次,我們還是看一下在雙核CPU上的運行結果吧:

Time = 297

Time = 297

Total time = 297

Time = 297

   可以看到在for循環裏的兩次test()函數調用都花費了297ms, 但是打印出的總時間卻只花費了297ms,後面那個單獨執行的test()函數花費的時間也是297ms,可見使用並行計算後效率提高了整整一倍。上面有講了使用最頻繁的編譯指導語句#pragma omp parallelfor,下面的博客會接着講一些最常用的一些編譯指導語句。

   最後說一下,如何在Visual Studio這個IDE中開啓OpenMP並行,打開過程如下:

   項目屬性->配置屬性->C\C++ ->語言->OpenMP支持->是 (/openmp)



參考文獻:

http://wenku.baidu.com/link?url=A-NdON4QI-9iKsRNrlw2mrqGoH2hynDhnZRXPpAWFJRnaNpoAx48tnVj3VYqieGzwJAWRlvR6cupiwCQ6rm0NlICCaPBT7cVVIkmHeHl8wa






發佈了48 篇原創文章 · 獲贊 146 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章