OpenMP 在 1997 年就開始了,一直維護改版至今。算是很穩定與老牌的函式庫了。
https://www.openmp.org/
https://zh.wikipedia.org/wiki/OpenMP
使用方法: (編輯 test.c)
#include // 引入library
#include
#include
int main(int argc, char* argv[])
{
#pragma omp parallel //這一行很重要
printf("Hello, world.\n");
return 1;
}
編譯方法: (編譯 test.c)
gcc -o test -fopenmp test.c
直接執行編譯出來的執行檔即可
解釋
語法
#pragma omp [clause[[,] clause] ...]
其中,directive共11個:
- atomic 記憶體位置將會原子更新(Specifies that a memory location that will be updated atomically.)
- barrier 執行緒在此等待,直到所有的執行緒都執行到此barrier。用來同步所有執行緒。
- critical 其後的程式碼塊為臨界區,任意時刻只能被一個執行緒執行。
- flush 所有執行緒對所有共用物件具有相同的記憶體視圖(view of memory)
- for 用在for迴圈之前,把for迴圈並列化由多個執行緒執行。迴圈變數只能是整型
- master 指定由主執行緒來執行接下來的程式。
- ordered 指定在接下來的程式碼塊中,被並列化的 for迴圈將依序執行(sequential loop)
- parallel 代表接下來的程式碼塊將被多個執行緒並列各執行一遍。
- sections 將接下來的程式碼塊包含將被並列執行的section塊。
- single 之後的程式將只會在一個執行緒(未必是主執行緒)中被執行,不會被並列執行。
- threadprivate 指定一個變數是執行緒局部儲存(thread local storage)
共計13個clause:
- copyin 讓threadprivate的變數的值和主執行緒的值相同。
- copyprivate 不同執行緒中的變數在所有執行緒中共用。
- default Specifies the behavior of unscoped variables in a parallel region.
- firstprivate 對於執行緒局部儲存的變數,其初值是進入並列區之前的值。
- if 判斷條件,可用來決定是否要並列化。
- lastprivate 在一個迴圈並列執行結束後,指定變數的值為迴圈體在順序最後一次執行時取得的值,或者#pragma sections在中,按文字順序最後一個section中執行取得的值。
- nowait 忽略barrier的同步等待。
- num_threads 設定執行緒數量的數量。預設值為目前電腦硬體支援的最大並行數。一般就是CPU的內核數目。超執行緒被作業系統視為獨立的CPU內核。
- ordered 使用於 for,可以在將迴圈並列化的時候,將程式中有標記 directive ordered 的部份依序執行。
- private 指定變數為執行緒局部儲存。
- reduction Specifies that one or more variables that are private to each thread are the subject of a reduction operation at the end of the parallel region.
- schedule 設定for迴圈的並列化方法;有 dynamic、guided、runtime、static 四種方法。
- schedule(static, chunk_size) 把chunk_size數目的迴圈體的執行,靜態依序指定給各執行緒。
- schedule(dynamic, chunk_size) 把迴圈體的執行按照chunk_size(預設值為1)分為若干組(即chunk),每個等待的執行緒獲得目前一組去執行,執行完後重新等待分配新的組。
- schedule(guided, chunk_size) 把迴圈體的執行分組,分配給等待執行的執行緒。最初的組中的迴圈體執行數目較大,然後逐漸按指數方式下降到chunk_size。
- schedule(runtime) 迴圈的並列化方式不在編譯時靜態確定,而是推遲到程式執行時動態地根據環境變數OMP_SCHEDULE 來決定要使用的方法。
- shared 指定變數為所有執行緒共用。
細節可參考 Wiki
沒有留言:
張貼留言