作者介紹
謝依暉
湖南大學(xué)碩士研究生在讀,
本科畢業(yè)于湖南大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)專(zhuān)業(yè)
本文調(diào)研了4篇與OpenMP優(yōu)化相關(guān)的文獻(xiàn),對(duì)優(yōu)化點(diǎn)分析如下:
面向Open64的OpenMP程序優(yōu)化[1]
跨越過(guò)程邊界的并行區(qū)重構(gòu)
Open64有著過(guò)程間分析優(yōu)化部件,因此可以知道哪些函數(shù)使用了被調(diào)函數(shù),從而可以通過(guò)在使用被調(diào)函數(shù)處放置合適的編譯指導(dǎo)語(yǔ)句來(lái)完成并行區(qū)重構(gòu)。
這樣做的好處是:
進(jìn)一步擴(kuò)大并行塊的大??;
將并行塊提升到調(diào)用函數(shù)中,便于進(jìn)一步對(duì)調(diào)用函數(shù)中的并行塊合并。
以下給出例子:
programmain callsub_procedure end subroutinesub_procedure !$ompparallel P !$ompendparallel end
優(yōu)化后:
programmain !$ompparallel callsub_procedure !$ompendparallel end subroutinesub_procedure P end
OpenMP并行編程模型與性能優(yōu)化方法的研究及應(yīng)用[2]
Cache命中率優(yōu)化
數(shù)組合并:定義兩個(gè)數(shù)組val[N]和key[N],在順序訪問(wèn)val[i]和key[i]時(shí)可能會(huì)導(dǎo)致Cache沖突失效,若改為struct merge{key, val}就可以通過(guò)提高空間局部性減少Cache失效次數(shù)。
循環(huán)交換:C按行存儲(chǔ)而Fortran按列存儲(chǔ),應(yīng)根據(jù)存儲(chǔ)的順序來(lái)訪問(wèn)。
提取關(guān)鍵數(shù)據(jù):提取關(guān)鍵數(shù)據(jù)可以減少重復(fù)存取的數(shù)據(jù),例如在排序中用關(guān)鍵字和指針代替整個(gè)記錄排序,這樣就能讓Cache無(wú)需存放無(wú)關(guān)數(shù)據(jù)而提高命中率。
分塊:對(duì)于極大大小的數(shù)組,要在Cache中一次容納整個(gè)數(shù)組是有困難的,但可以將數(shù)組分為多塊,可有效降低Cache失效率。
循環(huán)調(diào)度優(yōu)化
在OpenMP中可對(duì)并行循環(huán)指定調(diào)度方案,以將每個(gè)迭代分配給多個(gè)工作線程執(zhí)行。其一般形式如下:
#pragmaompforschedule(schedule_name,chunk_size) for(i=0;i
OpenMP編譯與優(yōu)化技術(shù)研究[3]
論文中給出了一種使用啟發(fā)式規(guī)則來(lái)估計(jì)各種額外開(kāi)銷(xiāo)和調(diào)度參數(shù)的關(guān)系,得到一個(gè)線性不等式組,可以通過(guò)求解該不等式組得到較優(yōu)的調(diào)度參數(shù)。
變量屬性的優(yōu)化
在OpenMP語(yǔ)句中每一次對(duì)變量的聲明都對(duì)應(yīng)一次新的地址分配。給出以下例子:
#pragmaompparallel { #pragmaompforprivate(a) {...} #pragmaompforprivate(a) {...} }
在如上代碼中,編譯器會(huì)為每個(gè)循環(huán)分配一個(gè)單獨(dú)的私有變量,而優(yōu)化后的代碼如下所示:
#pragmaompparallelprivate(a) { #pragmaompfor {...} #pragmaompfor {...} }
How to Get Good Performance by Using OpenMP[4]
去除依賴(lài)
對(duì)于某些循環(huán)語(yǔ)句,存在依賴(lài)而導(dǎo)致無(wú)法使用OpenMP優(yōu)化,但是這其中的某些依賴(lài)可以通過(guò)修改代碼去除依賴(lài)而使用OpenMP運(yùn)行代碼。
下列循環(huán)存在反依賴(lài):
for(inti=0;i
除去循環(huán)之間的依賴(lài)后:
#pragmaompparallelforshared(a,a_copy) for(inti=0;i
下列循環(huán)存在流依賴(lài):
for(inti=1;i
在loop skewing之后:
b[1]=b[1]+a[0] #pragmaompparallelforshared(a,b,c) for(inti=1;i
負(fù)載不均衡
下段代碼使用流水線形式處理,以塊的形式讀取數(shù)據(jù),然后處理每個(gè)塊并在下一個(gè)塊之前將結(jié)果寫(xiě)入磁盤(pán),造成極差的負(fù)載均衡。
for(i=0;i
接下來(lái)這段代碼使用動(dòng)態(tài)調(diào)度來(lái)重疊I/O和處理數(shù)據(jù),將上述流水線代碼并行化。
#pragmaompparallel { /*preloaddatatobeusedinfirstiterationofthei-loop*/ #pragmaompsingle {ReadFromFile(O,...);} for(i=0;i
解決偽共享問(wèn)題
inta[Nthreads][cache_line_size]; #pragmaompparallelforshared(Nthreads,a)schedule(static,1) for(inti=0;i
一般情況下,int型變量占四個(gè)字節(jié),A[0]和A[1]的地址只差四個(gè)字節(jié),小于一個(gè)Cache行,它們有著極大的可能在同一Cache行內(nèi),從而導(dǎo)致同時(shí)更新不同處理器的相同Cache行中的單個(gè)元素會(huì)導(dǎo)致整個(gè)Cache行無(wú)效。
對(duì)于False sharing問(wèn)題,一般可以通過(guò)填充數(shù)組來(lái)優(yōu)化。
inta[Nthreads][cache_line_size]; #pragmaompparallelforshared(Nthreads,a)schedule(static,1) for(inti=0;i
我們還對(duì)文獻(xiàn)中的部分優(yōu)化使用LLVM Flang編譯器和classic-flang編譯器進(jìn)行了測(cè)試,測(cè)試結(jié)果請(qǐng)參考https://gitee.com/src-openeuler/flang/pulls/22/files。
審核編輯:湯梓紅
-
優(yōu)化
+關(guān)注
關(guān)注
0文章
220瀏覽量
23847 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4260瀏覽量
62230 -
OpenMP
+關(guān)注
關(guān)注
0文章
12瀏覽量
5599
原文標(biāo)題:OpenMP優(yōu)化調(diào)研系列文章(3)
文章出處:【微信號(hào):openEulercommunity,微信公眾號(hào):openEuler】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論