openmp

OpenMP是由OpenMP Architecture Review Board牽頭提出的,並已被廣泛接受,用於共享記憶體並行系統的多處理器程式設計的一套指導性編譯處理方案(Compiler Directive)。OpenMP支持的程式語言包括CC++Fortran;而支持OpenMp的編譯器包括Sun Compiler,GNU Compiler和Intel Compiler等。OpenMp提供了對並行算法的高層的抽象描述,程式設計師通過在原始碼中加入專用的pragma來指明自己的意圖,由此編譯器可以自動將程式進行並行化,並在必要之處加入同步互斥以及通信。當選擇忽略這些pragma,或者編譯器不支持OpenMp時,程式又可退化為通常的程式(一般為串列),代碼仍然可以正常運作,只是不能利用多執行緒來加速程式執行。

基本介紹

  • 中文名:共享存儲並行編程
  • 外文名:Open Multi-Processing
  • 提出人:OpenMP Architecture 
  • 類型程式設計
  • 支持C語言C++Fortran
簡介,基本使用,相關信息,

簡介

OpenMP提供的這種對於並行描述的高層抽象降低了並行編程的難度和複雜度,這樣程式設計師可以把更多的精力投入到並行算法本身,而非其具體實現細節。對基於數據分集的多執行緒程式設計,OpenMP是一個很好的選擇。同時,使用OpenMP也提供了更強的靈活性,可以較容易的適應不同的並行系統配置。執行緒粒度和負載平衡等是傳統多執行緒程式設計中的難題,但在OpenMP中,OpenMP庫從程式設計師手中接管了部分這兩方面的工作。
但是,作為高層抽象,OpenMP並不適合需要複雜的執行緒間同步和互斥的場合。OpenMp的另一個缺點是不能在非共享記憶體系統(如計算機集群)上使用。在這樣的系統上,MPI使用較多。

基本使用

要在Visual C++2005 中使用OpenMP其實不難,只要將 Project 的Properties中C/C++里Language的OpenMP Support開啟(參數為 /openmp),就可以讓VC++2005 在編譯時支持OpenMP 的語法了;而在編寫使用OpenMP 的程式時,則需要先include OpenMP的頭檔案:omp.h。
而要將 for 循環並行化處理,該怎么做呢?非常簡單,只要在前面加上一行
#pragma omp parallel for
就夠了!
也可以實際用一段簡單的程式,來弄清楚它的運作方式。
#include <STDIO.H>
#include <STDLIB.H>
void Test(int n) {
for(int i = 0; i < 10000; ++i) {
//do nothing, just waste time
}
printf("%d, ", n);
}
int main(int argc,char* argv[]) {
for(int i = 0; i < 10; ++i)
Test(i);
system("pause");
}
上面的程式,在 main() 是一個很簡單的迴圈,跑十次,每次都會調用Test()這個函式,並把是迴圈的執行次數(i)傳進Test() 並列印出來。想當然,它的結果會是:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
而如果想利用 OpenMP把 main() 裡面的迴圈平行化處理呢?只需要修改成下面的樣子:
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
void Test (int n) {
for(int i = 0; i < 10000; ++i) {
//do nothing, just waste time
}
printf("%d, ", n);
}
int main(int argc,char* argv[]) {
#pragma omp parallel for
for(int i = 0; i < 10; ++i)
Test( i );
system("pause");
}
夠簡單吧?從頭到尾,只加了兩行!而執行後,可以發現結果也變了!
0, 5, 1, 6, 2, 7, 3, 8, 4, 9,
可以從結果很明顯的發現,他沒有照著0到9的順序跑了!而上面的順序怎么來的?其實很簡單,OpenMP只是把迴圈 0 - 9 共十個步驟,拆成 0 - 4, 5 - 9 兩部份,丟給不同的執行緒去跑,所以數字才會出現這樣交錯性的輸出~
而要怎么確定真的有跑多執行緒呢?如果本來有多處理器多核心處理器或有 Hyper Thread 的話,一個單執行緒程式,最多只會把一顆核心的使用量吃完;像比如說在 Pentium 4 HT 上跑,單一執行緒的程式,在工作管理員中看到的 CPU使用率最多就是 50%。而利用 OpenMP 把迴圈進行平行化處理後,就可以在執行迴圈時,把兩顆核心的 CPU 都榨光了!也就是CPU使用率是100%。

相關信息

多執行緒的概念
OpenMP是作為共享存儲標準而問世的。它是為在多處理機上編寫並行程式而設計的一個套用編程接口。它包括一套編譯指導語句和一個用來支持它的函式館。
當今雙核、四核的 CPU 當道,而六核的CPU也已經面世多時,所以在多處理機上編寫、運行並行程式會變得相當普遍。
對於一般單一執行緒(single thread)的程式,多核心處理器並沒有辦法提升它的處理效能;不過對於多執行緒(multi thread)的程式,就可以透過不同的核心同時計算,來達到加速的目的了!簡單的例子,以單執行緒的程式來說,一件事做一次要十秒的話,要做十次,都丟給同一顆核心做的話,自然就是 10 秒 * 10 次,也就是 100 秒了;但是以多執行緒的程式來說,它可以把這一件事,分給兩顆核心各自做,每顆核心各做 5 次,所以所需要的時間就只需要 50 秒!
當然,多執行緒的程式實際上沒這么簡單。在工作的切割、結合上,也是要多花時間的,所以在現實中,即使最佳狀況,雙核心的效能也不會是 1 + 1 = 2 這樣的理想化。除此之外,也不是所有工作都是可以切割的!很多工作是有關聯性的,這樣如果直接切割給不同的處理核心各自去並行運算,出來的結果是肯定有問題的。而且,多執行緒的程式在編寫、維護上,也都比單一執行緒的程式複雜上不少。
不過,如果電腦本身是多處理器多核心處理器,或是處理器擁有像 IntelHyper-ThreadingTechnology 這類的能在同一個時間處理多個執行緒的功能的話,那把各自獨立的工作由單一執行緒改成多執行緒,在執行的效率上,大多還是會有增進的!
多執行緒的程式
寫程式的時候該怎么去寫多執行緒的程式呢?一般的方法,就是真的利用執行緒的控制,去實際在程式中去產生其他的執行緒來處理。像 POSIX Threads 這套 library,就是用來產生、控制執行緒的函式庫。而像 Microsoft VisualStudio 2005 中,也有提供控制執行緒的功能。這種方法,大多就是產生多個 thread,而再由主執行緒把工作拆開,分給子執行緒去運算,最後再由主執行緒回收結果、整合。
但是,實際上要去控制執行緒是蠻麻煩的,在程式的編寫上,也會複雜不少;而如果我們只是想要把一些簡單的循環並行化處理,用執行緒庫來控制,實在有點殺雞用牛刀的感覺。這時候,用Open MP就簡單多了!OpenMP 是一種能透過高階指令,很簡單地將程式並行化、多執行緒化的 API;在最簡單的情形,甚至可以只加一行指令,就可以將循環內的程式並行化處理了!

相關詞條

熱門詞條

聯絡我們