1. 簡介
本檔會指定編譯程式指示詞、連結庫函式和環境變數的集合,可用來在 C 和 C++ 程式中指定共用記憶體平行處理原則。 本檔所述的功能統稱為 OpenMP C/C++ 應用程式程式介面(API)。 此規格的目標是為平行程序設計提供模型,讓程式能夠在來自不同廠商的共用記憶體架構之間移植。 許多廠商的編譯程式都支援 OpenMP C/C++ API。 如需 OpenMP 的詳細資訊,包括 OpenMP Fortran Application Program Interface,請參閱下列網站:
本文件中定義的指示詞、連結庫函式和環境變數可讓您建立和管理平行程式,同時允許可移植性。 指示詞會使用單一程式多個數據 (SPMD) 建構、工作共用建構和同步處理建構,來擴充 C 和 C++循序程序設計模型。 它們也支持數據的共用和私有化。 支援 OpenMP C 和 C++ API 的編譯程式包含可啟動及允許解譯所有 OpenMP 編譯程式指示詞之編譯程式的命令行選項。
1.1 範圍
此規格僅涵蓋使用者導向的平行處理,其中您明確定義編譯程式和運行時間系統平行執行程式所採取的動作。 不需要 OpenMP C 和C++實作來檢查相依性、衝突、死結、競爭狀況或其他導致程式執行不正確的問題。 您必須負責確保使用 OpenMP C 的應用程式,並C++ API 建構正確執行。 本檔未涵蓋編譯程式產生的自動平行處理和指示詞,以協助這類平行處理。
1.2 詞彙的定義
本檔案使用下列詞彙:
barrier
小組中所有線程都必須連線到的同步處理點。 每個線程會等到小組中的所有線程都到達此時為止。 實作所建立的指示詞和隱含屏障會識別明確屏障。
建構
建構是語句。 它是由 指示詞所組成,後面接著結構化區塊。 某些指示詞不是建構的一部分。 (請參閱附錄 C 中的 openmp-directive)。
指示詞
C 或 C++
#pragma
後面omp
接著標識碼、其他文字和新行。 指示詞會指定程序行為。動態範圍
語彙範圍中的所有語句,再加上在語彙範圍內執行語句而執行之函式內的任何語句。 動態範圍也稱為 區域。
語彙範圍
語句在結構化區塊中以語彙方式保留。
master thread
在輸入平行區域時建立小組的線程。
平行區域
系結至OpenMP平行建構且可由許多線程執行的語句。
private
私用變數會命名一個記憶體區塊,此區塊對進行參考的線程而言是唯一的。 有數種方式可以指定變數是私用的:平行區域內的定義、
threadprivate
指示詞、、、private
firstprivate
、lastprivate
或reduction
子句,或使用變數作為for
迴圈中的迴圈控件變數,緊接在for
或parallel for
指示詞之後for
。region
動態範圍。
序列區域
語句只會由任何平行區域的動態範圍以外的主要線程執行。
序列化
若要使用下列項目執行平行建構:
由單個線程組成的線程小組(這是該平行建構的主要線程),
結構化區塊內語句的序列執行順序(與區塊不是平行建構的一部分的順序相同),以及
除了任何巢狀平行建構的效果之外,不會對 所
omp_in_parallel()
傳回的值產生任何影響。
shared
共用變數會命名單一記憶體區塊。 存取此變數之小組中的所有線程也會存取此單一記憶體區塊。
結構化區塊
結構化區塊是具有單一專案和單一結束的語句(單一或複合)。 如果語句有跳入或跳出語句,該語句就是結構化區塊。 (此規則包含對 的
longjmp
呼叫(3C) 或使用throw
,雖然允許呼叫exit
。 如果它的執行一律從開頭{
開始,而且一律在結尾}
結束,則複合語句是結構化區塊。 表達式語句、selection 語句、反覆專案語句或try
區塊是結構化區塊,如果透過將它括在 中{
取得的對應複合語句,而且}
會是結構化區塊。 jump 語句、標記語句或宣告語句不是結構化區塊。團隊
在建構的執行中合作的一或多個線程。
thread
執行實體具有序列控制流程、一組私用變數,以及共用變數的存取權。
variable
命名空間名稱選擇性限定的標識碼,該標識符會命名物件。
1.3 執行模型
OpenMP 使用平行執行的分支聯結模型。 雖然這個分支聯結模型對於解決各種問題很有用,但它是針對大型數位型應用程式量身打造的。 OpenMP 旨在支援以平行程式的形式正確執行的程式(許多執行線程和完整的 OpenMP 支援連結庫)。 它也適用於以循序程序正確執行的程式(忽略指示詞和簡單的OpenMP存根連結庫)。 不過,可以且允許開發在循序執行時無法正確運作的程式。 此外,不同程度的平行處理原則可能會導致不同的數值結果,因為數值運算的關聯變更。 例如,序列加法縮減可能會有與平行縮減不同的加法關聯模式。 這些不同的關聯可能會變更浮點加法的結果。
以 OpenMP C/C++ API 撰寫的程式會開始執行,做為稱為 主要線程的單一執行線程。 主要線程會在序列區域中執行,直到遇到第一個平行建構為止。 在OpenMP C/C++ API 中,指示 parallel
詞會構成平行建構。 遇到平行建構時,主要線程會建立線程小組,而主要線程會成為小組的主圖形。 小組中的每個線程都會在平行區域的動態範圍中執行 語句,但工作共用建構除外。 小組中的所有線程都必須以相同順序遇到工作共用建構,而且一或多個線程會在相關聯的結構化區塊內執行 語句。 工作共用建構結尾所隱含的屏障,且沒有 nowait
子句,是由小組中的所有線程所執行。
如果線程修改共享物件,它不僅會影響它自己的執行環境,也會影響程式中的其他線程。 只有在宣告對象為揮發性時,才能從另一個線程的觀點,在下一個序列點(如基底語言中所定義)完成修改。 否則,在修改線程之後,一定會完成修改。 然後,其他線程(或同時)會看到 flush
指定物件的指示詞(隱含或明確)。 flush
當其他 OpenMP 指示詞所隱含的指示詞不保證副作用的正確順序時,程式設計人員有責任提供其他明確flush
指示詞。
平行建構完成時,小組中的線程會在隱含屏障上同步處理,而且只有主要線程會繼續執行。 單一程式中可以指定任意數目的平行建構。 因此,程式可能會在執行期間分叉並聯結多次。
OpenMP C/C++ API 可讓程式設計人員在平行建構內呼叫的函式中使用 指示詞。 未出現在平行建構語彙範圍的指示詞,但可能位於動態範圍中,稱為 孤立 指示詞。 使用孤立的指示詞,程式設計人員可以平行執行其程式的主要部分,且只會對循序程序進行最少的變更。 透過這項功能,您可以在程式呼叫樹狀結構的最上層撰寫平行建構的程序代碼,並使用指示詞來控制任何呼叫函式中的執行。
對 C 和 C++ 輸出函式的未同步處理呼叫,而這些函式會寫入相同的檔案,可能會導致不同線程寫入的數據以非決定性順序顯示輸出。 同樣地,從相同檔案讀取的輸入函式的未同步處理呼叫,可能會以非決定性的順序讀取數據。 I/O 的未同步處理使用,讓每個線程存取不同的檔案,會產生與 I/O 函式序列執行相同的結果。
1.4 符合標準
如果 OpenMP C/C++ API 的實作能夠辨識並保留此規格所有元素的語意,如第 1 章、2、3、4 和附錄 C.Appendices A、B、D、E 和 F 僅供資訊之用,且不屬於規格的一部分。 只包含 API 子集的實作不符合 OpenMP 規範。
OpenMP C 和 C++ API 是實作所支援之基底語言的延伸模組。 如果基底語言不支援本檔中出現的語言建構或延伸模組,則不需要 OpenMP 實作來支援它。
所有標準 C 和 C++ 連結庫函式和內建函式(也就是編譯程式具有特定知識的函式)都必須具有線程安全。 平行區域內不同線程對線程安全函式的同步處理使用,不會產生未定義的行為。 不過,行為可能與序列區域中的行為不同。 (隨機數產生函式是範例。
OpenMP C/C++ API 會指定特定行為是 實作定義的。 必須有一個符合 OpenMP 實作的實作,才能在這些情況下定義並記錄其行為。 如需實作定義行為的清單,請參閱 附錄 E。
1.5 規範參考
ISO/IEC 9899:1999, 資訊技術 - 程式設計語言 - C.此 OpenMP API 規格是指 ISO/IEC 9899:1999 作為 C99。
ISO/IEC 9899:1990, 資訊技術 - 程式設計語言 - C.此 OpenMP API 規格是指 ISO/IEC 9899:1990 作為 C90。
ISO/IEC 14882:1998、 資訊技術 - 程式設計語言 - C++。 此 OpenMP API 規格將 ISO/IEC 14882:1998 視為C++。
在此OpenMP API規格參考 C時,會參考實作所支援的基底語言。