跳轉至內容

OpenMP/概述

來自華夏公益教科書,開放的書籍,面向開放的世界

本書介紹了 OpenMP,一種 C(和 C++)語言擴充套件,允許輕鬆進行並行程式設計。要理解 OpenMP 的功能,首先需要了解並行程式設計是什麼以及它不是什麼。

並行程式設計 指編寫在多個計算裝置上同時執行的軟體。對於本書而言,“計算裝置”主要是處理器(CPU)或多核 CPU 內部的處理器核心,這是 OpenMP 3 的重點。在其他情況下,“計算裝置”可能指一個叢集中的一臺完整計算機,或者其他型別的裝置,如圖形處理單元(GPU)。英特爾已經設計了 OpenMP 到叢集計算的擴充套件,OpenMP 4 添加了對在非 CPU 裝置上執行程式碼的支援,但這些內容超出了本書的範圍。

並行程式設計主要是為了加速必須快速完成的計算。理想情況下,如果您的程式在n個計算裝置(核心)上執行,您希望該程式比在單個裝置上執行快n倍。在實踐中,這種情況永遠不會發生,因為計算裝置需要相互通訊,傳送和等待訊息,例如“給我你的計算結果”。儘管如此,並行程式設計仍然可以將許多應用程式的速度提高到幾乎等於n的倍數。

並行程式設計應該與併發程式設計區分開來,併發程式設計意味著將程式分解為概念上同時執行的程序。並行程式和併發程式之間存在相當大的重疊:兩者都涉及將任務分解為可以單獨執行的不同子任務,並且併發程式可以從在多個計算裝置上並行執行其任務中受益。但是,完整的併發程式設計與並行程式設計不同,因為通常併發任務之間的通訊型別不同於並行任務之間的通訊型別。

OpenMP 以非常乾淨的方式為 C 添加了對並行程式設計的支援。與執行緒庫不同,現有程式需要進行少量更改才能在多個處理器上並行執行。事實上,OpenMP 的基本結構是如此非侵入性,以至於使用它們但在不支援 OpenMP 的編譯器上編譯的程式仍然可以工作(儘管是順序的,當然)。為了瞭解這意味著什麼,請考慮以下 C 函式

void broadcast_sin(double *a, size_t n)
{
    #pragma omp parallel for
    for (size_t i = 0; i < n; i++) {
        a[i] = sin(a[i]);
    }
}

此函式在陣列上“廣播”正弦函式,並將結果儲存回同一個陣列。當在編譯器中啟用 OpenMP 時,它實際上將使用多個執行緒執行此操作,但在沒有 OpenMP 的情況下,它仍然可以正常工作併產生完全相同的效果。

分叉-合併模型的說明:程式分為多個部分(“分叉”),這些部分並行執行,並在完成後合併到一個順序部分。這在程式的生命週期中發生多次。

OpenMP 程式根據所謂的 分叉-合併模型工作,如右圖所示。OpenMP 執行時維護一個執行緒池,每次遇到並行部分時,它就會將工作分配給池中的執行緒。當所有執行緒都完成後,將恢復順序執行。

華夏公益教科書