openMP學習心得

最近發現前輩程序裏有使用openMP,不知道是幹嘛用是,所以,稍微學習了一下。最淺顯的理解就是openMP可以設置程序在多核裏的“並行”執行。這裏的“並行”是指程序裏面的一塊代碼是並行,而不是所有程序的並行執行。或者說,只是對於for循環的並行執行。

使用openMP時有兩個地方需要添加:

1.頭文件要#include<omp.h>

2.在VS2013(我用的VS2013)工程屬性中,設置支持“openMP”,如下圖所示



openMP指令有很多,這裏只介紹最簡單的對for循環是並行處理。如下,


一、#pragma omp parallel for  //默認是電腦核數,若是雙核,則會啓動2個線程,若是4核則會啓動四個線程。
for (int i = 0; i < 10; i++)
{
                 //具體程序

二、也可以設置線程數

omp_set_num_threads(4);//設置四個線程,注意:並不是線程數越多越好,當設置的線程數超出CPU核數時,意味着CPU核需要進行線程間調度,而調度則需要時間,會影                                                                      響速度

#pragma omp parallel for 
for (int i = 0; i < 10; i++)
{
                 //具體程序

三、openMP中的任務調度

問:爲什麼需要任務調度?

答:當for循環中每次迭代的計算量不相等時,如果簡單地給各個線程分配相同次數的迭代的話,會造成各個線程計算負載不均衡,這會使得有些線程先執行完,有些後執行完,造成某些CPU空閒,影響程序性能。例如:100次循環,分給四個線程,每個線程25次循環。恰好,第一個線程的25次循環都是加法,而後面的都是加減乘除的混合運算,很明顯第一個線程會很快執行完,造成CPU空閒。所以會出現線程間負載不均衡的問題,爲解決這些問題OpenMP 中提供了幾種對 for 循環並行化的任務調度方案。在 OpenMP 中,對 for 循環並行化的任務調度使用 schedule 子句來實現, 

schedule 子句的使用格式爲:
schedule(type[,size]) 

schedule 有兩個參數:type 和 size,size 參數是可選的
type 參數,表示調度類型,有四種調度類型如下:
· dynamic
· guided
· runtime
· static
這裏只介紹dynamic:
動態調度是動態地將迭代分配到各個線程,動態調度可以使用 size 參數也可以不使用 size 參數,不使用 size參數時是將迭代逐個地分配到各個線程,使用 size 參數時,每次分配給線程的迭代次數爲指定的 size 次 。
1)不使用size參數:
#pragma omp parallel for schedule(dynamic) 
for(int i=0;i<10;i++)
{
//循環體
}
若爲四核CPU,則默認四個線程,該程序運行時,i=0會給第一個線程,i=1會給第二個線程,i=2會給第三個線程,i=3會給第四個線程,i=4又給第一個......如此循環。
2)使用size參數
#pragma omp parallel for schedule(dynamic, 2)
for(i = 0; i < 10; i++ )
{
printf("i=%d, thread_id=%d\n", i, omp_get_thread_num());//omp_get_thread_num()會獲得線程ID,即第幾個線程
}

同樣爲四核CPU,i=0和i=1會給第一個線程,而i=2,i=3會給第二個線程,依次類推。

注意:在對for循環並行是時候,必須保證 for 循環裏的內容必須滿足可以並行執行,即每次循環互不相干,後一次循環不依賴亍前面的循環。


發佈了34 篇原創文章 · 獲贊 25 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章