OpenMP 指令格式 |
C / C++ 指令格式
格式:
#pragma omp | directive-name | [clause, ...] | newline |
OpenMP C/C++ 指令都需要. | 有效OpenMP 指令. 必須在pragma指令後,在 clauses指令前。 | 可選. 除非有另外的限制,子句可以任意順序, 根據需要重複。 | 必需. 位于被這個指令包圍的結構塊之前。 |
示例:
|
規則:
- 區分大小寫
- 指令遵守C/C++編譯器指令标準
- 每條指令隻能有一個指令名稱
- 每條指令适用于最少一條被結構塊包圍的語句
- 常指令可以在一條指令行結束後,用"/"連接配接
Fortran 指令格式
格式: (不區分大小寫)
sentinel | directive-name | [clause ...] |
所有的Fortan OpenMP指令必須以哨兵開始。 接受的哨兵依賴于Fortan源程式。可能的形式: | 有效OpenMP指令,必須在哨兵和子句之間。 | 可選.除非有另外的限制,子句可以任意順序, 根據需要重複。 |
示例:
|
固定格式源:
- !$OMP C$OMP *$OMP 作為接受的哨兵,必須出現在第一列
- 所有Fortan的固定規則,比如行長度,空格,繼續,注釋等,對整條指令都适合
- 初始指令行必須在第六列包含一個空格/0
- 接下來的指令行在第六列必須包含一個非空格/0
自由格式源:
- !$OMP 是唯一的接受哨兵. 可以出現在任何列,但必須前面隻能有空格
- 所有Fortan的自由規則,比如行長度,空格,繼續,注釋等,對整條指令都适合
- 初始指令行之後必須有個空格
- 後續行的每一行,最後都必須有個作為非空白字元的符号
規則:
- 注釋不能作為指令出現在同一行
- 每條指令隻能指定一個指令名稱
- 啟用了OpenMP的Fortran編譯器通常包含一條指令行選項,用來訓示編譯器激活并解釋所有的OpenMP指令
- 幾個Fortran OpenMP指令成對出現,格式如下所示. "end"是可選的,但為了提高可讀性,建議不要省略.
|
OpenMP 指令 |
指令作用域
不羅嗦了...
靜态範圍:
- 代碼由一條OpenMP的指令開頭,寫在一個結構塊的開始和結束之間
- 指令的靜态範圍不能跨越多個例程或代碼檔案
孤立指令:
- 看起來和另外一個包圍指令沒有關系的指令被稱為孤立指令。 它存在于另外一個指令的靜态範圍之外。
- 跨越多個例程(也許是代碼檔案)
Dynamic Extent動态範圍:
- 指令的動态範圍包括它的靜态範圍以及孤立指令範圍.
Example:
| |
靜态範圍 并行區域内的DO 指令 | 孤立指令 并行區域外的CRITICAL 和SECTIONS 指令 |
動态範圍 CRITICAL 和SECTIONS 指令在DO 和PARALLEL 指令的動态範圍内. |
為什麼這一點很重要?
- OpenMP 制定了一系列關于指令關聯(綁定)與嵌套的範圍規則
- 如果OpenMP的綁定與嵌套規則被忽略,可能導緻程式非法或不正确
- 有關細節請參考Directive Binding and Nesting Rules
并行區域結構
作用:
- 并行區域是一塊能被多個線程執行的代碼。下面是基本的OpenMP并行結構:
格式:
Fortran | |
C/C++ | |
注意:
- 當線程遇到一個PARALLEL指令,它建立一組線程并成為主要者。主要者也屬于這組線程,并在組内的線程号為0
- 從這個并行區域開始,代碼被複制并被所有線程執行
- 并行區域結束時有個隐藏的關卡,隻有主要線程能在此之後繼續執行
- 并行區域内的任何線程終止都會終止所有的線程。工作不能繼續,直到這點被消除定義。
有多少線程?
- 并行區域内的線程數量是由以下因素決定的,按優先級排序:
- IF 子句的值
- NUM_THREADS 子句的設定
- 使用 omp_set_num_threads() 庫函數
- OMP_NUM_THREADS 環境變量
- 預設實作-一般是一個計算機的CPU數量,也可能是動态的(參考下節).
- 線程編号從0 (主線程) to N-1
動态線程:
- 用 omp_get_dynamic() 庫函數檢測動态線程是否被啟用.
- 如果支援動态線程,下面兩個方法可以啟用動态線程:
- omp_set_dynamic() 庫例程
- 設定 OMP_DYNAMIC 環境變量為TRUE
嵌套并行區域:
- 使用 omp_get_nested() 庫函數檢測嵌套并行區域是否被啟用.
- 如果支援嵌套并行區域,可以用下面兩個方法啟用:
- omp_set_nested() 庫例程
- 設定OMP_NESTED 環境變量為TRUE
- 如果不支援,嵌套并行區域預設将生成一個由單個線程組成的新組。
子句:
- IF 子句:如果存在,值必須為 .TRUE. (Fortran) 或者非零(C/C++) 以使能建立一組線程. 否則,此區域将被主線程串行執行.
- 在Data Scope Attribute Clauses 章節,将詳細讨論剩下的子句.
限定:
- 一個并行區域必須是一個結構塊,不能跨越多個程式或者代碼檔案
- 進入或者離開一個并行區域的分支都是非法的
- 隻允許一個IF子句
- 隻允許一個NUM_THREADS子句
Example: Parallel Region
- "Hello World" 程式
- 每一個線程都執行了并行區域的全部代碼
- OpenMP 庫例程用來獲得線程辨別與總線程數量
Fortran - Parallel Region Example |
·
C / C++ - Parallel Region Example |