OpenMP中幾個容易混淆的函數(線程數量/線程ID/線程最大數)以及並列區域線程數量的確定

來源:互聯網
上載者:User

說明:這部分內容比較基礎,主要是分析幾個容易混淆的OpenMP函數,加以理解。

(1)並列區域數量的確定:

在這裡,先回顧一下OpenMP的parallel並列區域線程數量的確定,對於一個並列區域,有一個team的線程去執行,那麼該分配多少個線程去執行呢?

OpenMP的遇到parallel指令後建立的線程team的數量由如下過程決定:

1. if子句的結果

2. num_threads的設定

3. omp_set_num_threads()庫函數的設定

4. OMP_NUM_THREADS環境變數的設定

5. 編譯器預設實現(一般而言,預設實現的是匯流排程數等於處理器的核心數)

(http://blog.csdn.net/gengshenghong/article/details/6956878查看更多資訊)

2、3、4優先順序依次降低的,也就是前面的設定可以覆蓋後面的設定,當然也是相對而言,num_threads子句只會影響當前的並列區域,而omp_set_num_threads對OMP_NUM_THREADS環境變數的覆蓋是在整個程式運行期間全域的。

(2)幾個容易混淆的OpenMP函數

1. omp_get_thread_num

擷取線程的num,即ID。這裡的ID是OpenMP的team內的ID,在OpenMP中,一個team內的線程的ID是俺順序排列的,0、1、2...

說明:此函數在並列區域外或者並列區域內都可以調用。在並列區域外,擷取的是master線程的ID,即為0。在並列區域內,每次執行到此函數,擷取的是當前執行線程的ID。

此函數比較容易理解,主要是不要和下面的omp_get_num_threads記混淆了。

2. omp_get_num_threads/omp_set_num_threads

設定/擷取線程數量,此set函數是上面確定遇到parallel指令後建立team的線程的決定方式之一,用於覆蓋OMP_NUM_THREADS環境變數的設定。

說明:儘管從函數名上看,它們是一對set/get函數,但是要區分它們的含義,set之後馬上get,其值不一定等於set的結果,而且大部分情況都是不相等的!

首先來理解omp_set_num_threads():

作用上來說,我們知道它是用於覆蓋環境變數OMP_NUM_THREDS的設定的,使用上來說,要注意的是,omp_set_num_threads只能用於並列區域之外,如果用於並列區域之內,在Debug下運行時會輸出“User Error 1001: omp_set_num_threads should only be called in serial regions”到控制台,如果是Release模式不會輸出,理論上應該是被忽略了。總之,在串列代碼區調用omp_set_num_threads來設定線程數量

然後分析omp_get_num_threads():

用於擷取當前線程組(team)的線程數量,如果不在並行區調用,返回1.

這句話就清楚了描述了get的作用了,擷取的是當前線程組的線程數量,所以一般會在並列區域調用,其返回的是實際的parallel地區內由上面幾大因素決定之後的實際的啟動並執行線程數量,並不是set的值,所以也很容易理解,在串列區調用它會返回1(所以一般也不會在串列區去調用)。

總結:omp_set_num_threads在串列地區調用才會有效,omp_get_num_threads擷取當前線程組的線程數量,一般在並列區域調用,在串列地區調用返回為1。兩個函數沒有本質上的數量關係!

3. omp_get_max_threads:

從函數名看,貌似是“擷取最大的線程數量”,是的,那麼這個“最大的線程數量"的具體含義呢?下面是OpenMP文檔上的一段話:

The omp_get_max_threads routine returns an upper bound on the number of threads that could be used to form a new team if a parallel region without a num_threads clause were encountered after execution returns
from this routine。

很清楚的說明了,這個”最大數量“是指在不使用num_threads的情況下,OpenMP形成一個新的team能建立的最大線程數量。從這裡要理解到:這個最大數量,是能確定的,與其在並列區域調用,還是在串列地區調用是無關的,因為它是返回OpenMP當前環境下去建立一個”新的“team能建立的可能的最大數量。簡單的理解,其實,這個值就是由以下三者確定:omp_set_num_threads、OMP_NUM_THREADS、編譯器預設實現。

注意:omp_get_max_threads可以在串列或並列區域內調用,而且其結果是一樣的(在其間不調用omp_set_num_threads的情況下),如果有效調用(串列區調用)了omp_set_num_threads,會改變接下來調用omp_get_max_threads的值。另外,omp_get_max_threads的傳回值可能會小於omp_set_num_threads。

4. 執行個體:

下面的例子是使用上面幾個函數的例子,根據結果可以分析出上面提到的一些內容:

#include <omp.h>int main(int argc, _TCHAR* argv[])  {printf("ID: %d, Max threads: %d, Num threads: %d \n",omp_get_thread_num(), omp_get_max_threads(), omp_get_num_threads());omp_set_num_threads(5);printf("ID: %d, Max threads: %d, Num threads: %d \n",omp_get_thread_num(), omp_get_max_threads(), omp_get_num_threads());#pragma omp parallel num_threads(5){// omp_set_num_threads(6);// Do not call it in parallel regionprintf("ID: %d, Max threads: %d, Num threads: %d \n",omp_get_thread_num(), omp_get_max_threads(), omp_get_num_threads());}printf("ID: %d, Max threads: %d, Num threads: %d \n",omp_get_thread_num(), omp_get_max_threads(), omp_get_num_threads());omp_set_num_threads(6);printf("ID: %d, Max threads: %d, Num threads: %d \n",omp_get_thread_num(), omp_get_max_threads(), omp_get_num_threads());return 0;  }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.