新聞中心
OpenMP中,任務(wù)調(diào)度主要用于并行的for循環(huán)中,當(dāng)循環(huán)中每次迭代的計算量不相等時,如果簡單地給各個線程分配相同次數(shù)的迭代的話,會造成各個線程計算負載不均衡,這會使得有些線程先執(zhí)行完,有些后執(zhí)行完,造成某些CPU核空閑,影響程序性能。例如以下代碼:

成都創(chuàng)新互聯(lián)是專業(yè)的蘭考網(wǎng)站建設(shè)公司,蘭考接單;提供做網(wǎng)站、網(wǎng)站設(shè)計,網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進行蘭考網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!
- int i, j;
- int a[100][100] = {0};
- for ( i =0; i < 100; i++)
- {
- for( j = i; j < 100; j++ )
- {
- a[i][j] = i*j;
- }
- }
如果將最外層循環(huán)并行化的話,比如使用4個線程,如果給每個線程平均分配25次循環(huán)迭代計算的話,顯然i=0和i=99的計算量相差了100倍,那么各個線程間可能出現(xiàn)較大的負載不平衡情況。為了解決這些問題,OpenMP中提供了幾種對for循環(huán)并行化的任務(wù)調(diào)度方案。
在OpenMP中,對for循環(huán)并行化的任務(wù)調(diào)度使用schedule子句來實現(xiàn),下面介紹schedule字句的用法。
?1.1.1Schedule子句用法
schedule子句的使用格式為:
- schedule(type[,size])
schedule有兩個參數(shù):type和size,size參數(shù)是可選的。
1. type參數(shù)
表示調(diào)度類型,有四種調(diào)度類型如下:
- dynamic
- guided
- runtime
- static
這四種調(diào)度類型實際上只有static、dynamic、guided三種調(diào)度方式,runtime實際上是根據(jù)環(huán)境變量來選擇前三種中的某中類型。
run-sched-var
2. size參數(shù) (可選)
size參數(shù)表示循環(huán)迭代次數(shù),size參數(shù)必須是整數(shù)。static、dynamic、guided三種調(diào)度方式都可以使用size參數(shù),也可以不使用size參數(shù)。當(dāng)type參數(shù)類型為runtime時,size參數(shù)是非法的(不需要使用,如果使用的話編譯器會報錯)。
1.1.2靜態(tài)調(diào)度(static)
當(dāng)parallel for編譯指導(dǎo)語句沒有帶schedule子句時,大部分系統(tǒng)中默認采用static調(diào)度方式,這種調(diào)度方式非常簡單。假設(shè)有n次循環(huán)迭代,t個線程,那 么給每個線程靜態(tài)分配大約n/t次迭代計算。這里為什么說大約分配n/t次呢?因為n/t不一定是整數(shù),因此實際分配的迭代次數(shù)可能存在差1的情況,如果 指定了size參數(shù)的話,那么可能相差一個size。
靜態(tài)調(diào)度時可以不使用size參數(shù),也可以使用size參數(shù)。
3.不使用size參數(shù)
不使用size參數(shù)時,分配給每個線程的是n/t次連續(xù)的迭代,不使用size參數(shù)的用法如下:
schedule(static)
例如以下代碼:
- #pragma omp parallel for schedule(static)
- for(i = 0; i < 10; i++ )
- {
- printf("i=%d, thread_id=%d/n", i, omp_get_thread_num());
- }
上面代碼執(zhí)行時打印的結(jié)果如下:
i=0, thread_id=0
i=1, thread_id=0
i=2, thread_id=0
i=3, thread_id=0
i=4, thread_id=0
i=5, thread_id=1
i=6, thread_id=1
i=7, thread_id=1
i=8, thread_id=1
i=9, thread_id=1
可以看出線程0得到了0~4次連續(xù)迭代,線程1得到5~9次連續(xù)迭代。注意由于多線程執(zhí)行時序的隨機性,每次執(zhí)行時打印的結(jié)果順序可能存在差別,后面的例子也一樣。
4. 使用size參數(shù)
使用size參數(shù)時,分配給每個線程的size次連續(xù)的迭代計算,用法如下:
- schedule(static, size)
例如以下代碼:
- #pragma omp parallel for schedule(static, 2)
- for(i = 0; i < 10; i++ )
- {
- printf("i=%d, thread_id=%d/n", i, omp_get_thread_num());
- }
執(zhí)行時會打印以下結(jié)果:
i=0, thread_id=0
i=1, thread_id=0
i=4, thread_id=0
i=5, thread_id=0
i=8, thread_id=0
i=9, thread_id=0
i=2, thread_id=1
i=3, thread_id=1
i=6, thread_id=1
i=7, thread_id=1
從打印結(jié)果可以看出,0、1次迭代分配給線程0,2、3次迭代分配給線程1,4、5次迭代分配給線程0,6、7次迭代分配給線程1,…。每個線程依次分配到2次連續(xù)的迭代計算。
#p#
1.1.3動態(tài)調(diào)度(dynamic)
動態(tài)調(diào)度是動態(tài)地將迭代分配到各個線程,動態(tài)調(diào)度可以使用size參數(shù)也可以不使用size參數(shù),不使用size參數(shù)時是將迭代逐個地分配到各個線程,使用size參數(shù)時,每次分配給線程的迭代次數(shù)為指定的size次。
下面為使用動態(tài)調(diào)度不帶size參數(shù)的例子:
- #pragma omp parallel for schedule(dynamic)
- for(i = 0; i < 10; i++ )
- {
- printf("i=%d, thread_id=%d/n", i, omp_get_thread_num());
- }
打印結(jié)果如下:
i=0, thread_id=0
i=1, thread_id=1
i=2, thread_id=0
i=3, thread_id=1
i=5, thread_id=1
i=6, thread_id=1
i=7, thread_id=1
i=8, thread_id=1
i=4, thread_id=0
i=9, thread_id=1
下面為動態(tài)調(diào)度使用size參數(shù)的例子:
- #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());
- }
打印結(jié)果如下:
i=0, thread_id=0
i=1, thread_id=0
i=4, thread_id=0
i=2, thread_id=1
i=5, thread_id=0
i=3, thread_id=1
i=6, thread_id=0
i=8, thread_id=1
i=7, thread_id=0
i=9, thread_id=1
從打印結(jié)果可以看出第0、1,4、5,6、7次迭代被分配給了線程0,第2、3,8、9次迭代則分配給了線程1,每次分配的迭代次數(shù)為2。
1.1.4guided調(diào)度(guided)
guided調(diào)度是一種采用指導(dǎo)性的啟發(fā)式自調(diào)度方法。開始時每個線程會分配到較大的迭代塊,之后分配到的迭代塊會逐漸遞減。迭代塊的大小會按指數(shù)級下降到指定的size大小,如果沒有指定size參數(shù),那么迭代塊大小最小會降到1。
例如以下代碼:
- #pragma omp parallel for schedule(guided,2)
- for(i = 0; i < 10; i++ )
- {
- printf("i=%d, thread_id=%d/n", i, omp_get_thread_num());
- }
打印結(jié)果如下:
i=0, thread_id=0
i=1, thread_id=0
i=2, thread_id=0
i=3, thread_id=0
i=4, thread_id=0
i=8, thread_id=0
i=9, thread_id=0
i=5, thread_id=1
i=6, thread_id=1
i=7, thread_id=1
第0、1、2、3、4次迭代被分配給線程0,第5、6、7次迭代被分配給線程1,第8、9次迭代被分配給線程0,分配的迭代次數(shù)呈遞減趨勢,最后一次遞減到2次。
1.1.5runtime調(diào)度(rumtime)
runtime調(diào)度并不是和前面三種調(diào)度方式似的真實調(diào)度方式,它是在運行時根據(jù)環(huán)境變量OMP_SCHEDULE來確定調(diào)度類型,最終使用的調(diào)度類型仍然是上述三種調(diào)度方式中的某種。
例如在unix系統(tǒng)中,可以使用setenv命令來設(shè)置OMP_SCHEDULE環(huán)境變量:
setenv OMP_SCHEDULE “dynamic, 2”
上述命令設(shè)置調(diào)度類型為動態(tài)調(diào)度,動態(tài)調(diào)度的迭代次數(shù)為2。
在windows環(huán)境中,可以在”系統(tǒng)屬性|高級|環(huán)境變量”對話框中進行設(shè)置環(huán)境變量。
本文標(biāo)題:OpenMP中的任務(wù)調(diào)度
網(wǎng)站網(wǎng)址:http://www.dlmjj.cn/article/dpigjdp.html


咨詢
建站咨詢
