OpenMP知识点汇总
1. OpenMP(Open Multi-Processing)官網:http://openmp.org/wp/
2. OpenMP最新版本4.0,2013年7月發布。Visual Studio 2010內置支持OpenMP2.0,選中工程屬性->C/C++->Language->Open MP Support:選中Yes(/openmp)即可,然后在文件中加入#include <omp.h>就可使用OpenMP了。
3. 使用OpenMP前提是機子本身是多處理器或多核的并支持共享內存。內存是共享的,處理器在訪問內存的時候使用的是相同的內存編址空間,某一個處理器寫入內存的數據會立刻被其它處理器訪問到。它可以在大多數的操作系統中運行,如Linux、Mac OS、Microsoft Windows。
4. 其它開發工具的支持:(1)、GCC4.9:OpenMP4.0;(2)、VisualStudio 2005/2008/2010/2013:OpenMP2.0.
5. The OpenMP Architecture Review Board負責OpenMP新版本的發布,是非盈利公司,其成員包括:AMD、Cray、HP、IBM、Intel、NVIDIA、Oracle、Red Hat等,其標準是由一些具有國際影響力的軟件和硬件廠商共同定義和提出,其標準形成于1997年。在2002年發布了C/C++語言的2.0版本。
6. OpenMP本身是一個API規范,它沒有License,或者說它與編譯器具有相同的License.
7. 多核系統并行程序設計中需要重點關注的關鍵問題有兩個:(1)、設計適合多核系統運行的并行程序;(2)、優化多核系統中單個程序并行運行和多個程序同時并行運行的效率。
8. OpenMP本身不是一種獨立的并行語言,而是為多處理器上編寫并行程序而設計的、指導共享內存、多線程并行的編譯制導指令和應用程序編程接口(API),可在C/C++/Fortran中應用,用于編寫可移植的多線程應用程序。OpenMP程序設計模型提供了一組與平臺無關的編譯制導、API函數集和環境變量,可以顯示地指導編譯器如何以及何時利用應用程序中的并行性。所有OpenMP的并行化都是通過使用嵌入到C/C++/Fortran源代碼中的編譯制導語句來達到的。
9. OpenMP在串行代碼中以編譯器可識別的注釋形式出現,而這些注釋的解析由編譯器所完成。OpenMP是獨立于平臺的,如果編譯器不支持OpenMP,將會自動忽略預處理指令#pragma,程序依然可以按照串行程序代碼順利編譯執行。
10. OpenMP的執行模型采用fork-join(分叉-合并)的形式,以線程為基礎。其中fork創建線程或者喚醒已有線程;join即多線程的會合。fork-join執行模型在剛開始執行的時候,只有一個稱為“主線程”的運行線程存在。主線程在運行過程中,當遇到需要進行并行計算的時候,,派生出線程來執行并行任務。在并行執行的時候,主線程和派生線程共同工作。在并行代碼執行結束后,派生線程退出或者阻塞,不再工作,控制流回到單獨的主線程中。并行部分沒有結束是不會執行串行部分的。
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? fork-join并行執行模型
11. 運用OpenMP方法的加速比遠小于CPU核心數,這是因為OpenMP調度和同步需要一定的消耗。因此,在實際的編程開發中,要仔細分析代碼的性能瓶頸,在合理的位置設置代碼的并行化處理。
12. 串行程序僅僅利用了多核處理器中的一個處理核心,而其他處理核心則處于空閑狀態。采用多線程技術是提高資源利用率的一個有效方法,在單核處理器時代,應用程序已經支持多線程技術。然而,單核內的多線程運行是串行的,在某一時刻,只能有一段代碼被CPU執行,單核處理器只能將多個指令流交錯執行,輪流使用CPU,并不能真正將它們同時執行。在多核平臺,各線程都是在相互獨立的執行核上并行運行的,如果線程數目小于等于執行核數目,那么各行程在運行時相互之間不存在對CPU資源的競爭,在某一時刻,可以有多個線程同時運行,達到真正意義上的并行處理。
13. OpenMP缺點:(1)、不適合需要復雜的線程間同步和互斥的場合;(2)、只能在共享內存機上運行;(3)、可維護性不夠好;(4)、可擴展性差;(5)、支持OpenMP的編譯器一般不會自動檢測是否可以正確地執行需要并行化處理的代碼;(6)、不容易調試;(7)、需要一個支持OpenMP的編譯器;(8)、在GPU上不能使用;(9)、多線程的可執行文件的啟動需要更多的時間,可能比單線程的運行的慢,因此,使用多線程一定要有其他有優勢的地方;(10)、很多情況下使用多線程不僅沒有好處,還會帶來一些額外消耗。
14. OpenMP優點:(1)、代碼書寫簡單、開發時間短,不需要顯示設置互斥鎖、條件變量、數據范圍以及初始化,通信是隱式的;(2)、移植性好,完全是與平臺無關的;(3)、當帶有并行結構的應用程序運行在沒有多個處理器或硬件線程的目標平臺上時,OpenMP會使用單線程模式,這樣并不會帶來額外的系統開銷;(4)、在一般情況下,使用OpenMP并行時原始的(串行)代碼語句不需要進行修改,這減少不經意間引入錯誤的機會;(5)、數據分布和分解由指令自動完成。
15. 多核計算機的各個處理器都配備有自己的局部高速緩存(Cache),處理器訪問自身局部緩存的速度要比訪問主存或訪問其他處理器的緩存快得多。因此并行化設計必須考慮如何合理地使用緩存,以避免在讀寫數據時產生相關沖突。為了實現快速訪問緩存,對于多重嵌套循環體的并行化設計,必須遵循如下規則:第一,盡量并行化最外層循環,使得在并行區域內獲得最大的計算工作量,增加其并行粒度;第二,最里層的循環變量應該是變換最快的可變下標變量,而且在最里層應該按照順序訪問數組元素,也就是應按數組列訪問。這樣可以提高緩存局部性。因此,數組的最左下標變量應當作為最里層的循環變量,可以保證從主存按數組列順序把數組元素取出并放入緩存之中,從而達到快速訪問緩存,提高并行效率的目的。
16. OpenMP要求并行化的代碼中沒有互相關聯的變量。
17. 編程人員一定要將并行環境中的代碼運行結果與單線程環境下的該程序運行結果繼續校驗,以確保并行化后的代碼的正確性。
18. OpenMP并行區域引用到的變量都是所有線程間共享的,三種特例除外:(1)、并行循環中的循環變量是私有的;(2)、并行區域中聲明的變量是私有變量;(3)、通過private、firstprivate、lastprivate以及reduction子句聲明的變量是私有變量。
19. OpenMP標準并不保證程序語義的正確性,所以,這種轉化并不一定會提高程序的性能,甚至在最壞的情況下,會帶來錯誤的結果。
20. OpenMP并行程序的編譯器優化:(1)、OpenMP執行過程中,串行執行和并行執行切換帶來的額外執行開銷是影響OpenMP程序性能的一個重要因素;(2)、OpenMP實現共享內存編程模式,當兩個或多個處理器讀寫相同的內存單元時,要依靠同步來保證程序的正確性,barrier是一種常用的同步方式,barrier也是影響并行性能的重要因素之一。編譯器優化的目標是通過減少并行區和barrier數目,降低并行執行的開銷,提高程序的性能。
21.? 在C/C++程序中,OpenMP的所有編譯制導指令是以#pragma omp開始,后面跟具體的功能指令(或命令)。其中指令或命令是可以單獨出現的,而子句必須出現在制導指令之后。
22. 編譯制導指令:(1)、parallel for:for循環語句之前(限制:具有規范的格式,能夠推測出循環的次數,在循環過程中不能使用break、goto、return語句,可以使用continue語句,循環計算的過程中沒有循環依賴性);(2)、parallel sections:多個結構塊語句;(3)、single:只被單個線程執行的代碼;(4)、critical:用在一段代碼臨界區之前,保證每次只有一個OpenMP線程進入;(5)、barrier:線程同步。
23.? OpenMP的子句:(1)、firstprivate:繼承主線程中同名變量的值作為初值;(2)、lastprivate:將私有變量的值在并行處理結束后復制到主線程中的同名變量;(3)、reduction:歸約運算,并將結果返回給主線程同名變量。使用要求:僅在一次歸約中列出歸約變量,它們無法聲明為常量,且它們在并行結構中無法聲明為私有;(5)、nowait:忽略barrier同步;(6)、schedule:for中任務分配調度類型,包括static、 dynamic、 guided、 runtime;(7)、private:用來將一個或多個變量聲明成線程私有的變量。
24. 調試:首先,請務必意識到大多數錯誤都是競態條件。大多數競態條件都是由實際應被聲明為私有變量的共享變量引起的。首先應查看并行區域內的變量,確保這些變量在需要時被聲明為私有。同時,應檢查并行結構內部被調用的函數。在默認情況下,堆棧上聲明的變量為私有變量,但C/C++關鍵詞static會改變將放在全局堆上的變量,從而使其被OpenMP循環共享。另一個常見錯誤是使用未經初始化的變量。請謹記私有變量在進行并行結構時沒有初始值。請僅在需要時使用firstprivate和lastprivate子句來對它們進行初始化,否則會增加大量額外的開銷。
25. OpenMP線程化應用的性能主要取決于以下幾點:(1)、單線程代碼的潛在性能;(2)、CPU占用率、閑置線程和負載平衡不足;(3)、并行執行的應用的比例;(4)、線程之間的同步和通信數量;(5)、創建、管理、銷毀和同步化線程所需的開銷因fork-join轉換(從單線程到并行線程或從并行線程到單線程的轉換)的次數的增加而增加;(6)、內存、總線帶寬和CPU執行單元等共享資源的性能限制;(7)、由共享內存或錯誤共享內存引起的內存沖突。
26. 請記住:一旦采用了OpenMP,線程數量就將由編譯器來決定(而不是您),因此無論線程數量如何,重要的是使程序能夠正常運行。
27. OpenMP鎖在使用前需要進行初始化,不再使用時要解鎖。
28. 使用reduction子句進行多線程程序設計時,要記住以下三個要點:(1)、在第一個線程到達指定了reduction子句的共享區域或循環末尾時,原來的歸約變量的值變為不確定,并保持此不確定狀態直至歸約計算完成;(2)、如果在一個循環中使用到了reduction子句,同時又使用了nowait子句,那么在確保所有線程完成歸約計算的柵欄同步操作之前,原來的歸約變量的值將一直保持不確定的狀態;(3)、各個線程的私有副本值被歸約的順序是未指定的。因此,對于同一段程序的一次串行執行和一次并行執行,甚至兩次并行執行來說,都無法保證得到完全相同的結果(這主要針對浮點計算而言),也無法保證計算過程中諸如浮點計算異常這樣的行為會完全相同。
29. 如果是類(class)類型的變量使用在lastprivate參數中,那么使用時有些限制,需要一個可訪問的,明確的缺省構造函數,除非變量也被使用作為firstprivate子句的參數;還需要一個拷貝賦值操作符,并且這個拷貝賦值操作符對于不同對象的操作順序是未指定的,依賴于編譯器的定義。
參考文獻:http://blog.csdn.net/fengbingchun/article/details/15027507
GitHub:OpenMP test code
總結
以上是生活随笔為你收集整理的OpenMP知识点汇总的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《OpenMP编译原理及实现技术》摘录
- 下一篇: OpenCV中resize函数五种插值算