作者介紹
謝依暉
湖南大學碩士研究生在讀,
本科畢業于湖南大學計算機科學與技術專業
Abstract
本文調研了一些對OpenMP進行優化的方法:
H. Ma, R. Zhao, X. Gao and Y. Zhang針對OpenMP程序中的barrier提出幾種新功能的支持和性能的優化[1];
在SC20的Booth Talks上,Johannes Doerfert分享了在LLVM上對OpenMP做的一些優化[2]。
Barrier Optimization for OpenMP Program[1]
刪除冗余的barrier
通過并行數據流分析,兩個循環之間無數據依賴,所以S1的barrier是冗余的;parallel結束的時候有一個隱式的barrier,所以S2的barrier也是冗余的。
!$ompparallel !$ompdo doi=1,100 a(i)=d(i) enddo!barrierS1 !$ompenddo !$ompdo doi=1,100 b(i)=c(i) enddo!barrierS2 !$ompenddo !$ompendparallel
優化時,可以在該語句塊加上顯式的nowait(!$omp end do nowait)。
當并行化循環的時候,如果循環依賴距離是一個常數,如下代碼:
doi=2,100 doj=2,100 a(i,j)=a(i-1,j)+a(i,j-1) enddo enddo
對外層循環i進行數據依賴檢查,可以得到a[i][j]和a[i-1][j]之間的依賴距離為1。因此循環可以以DOACROSS并行的方式運行。OpenMP只實現了DOALL并行,沒有與DOACROSS對應的語句。
實現時,定義共享數組“_mylocks [ threadid ]”來存儲每個線程的事件,定義私有變量_counter0指示當前線程正在等待的事件。數組“_mylocks”中的元素總數是線程數,每個元素表示相應線程的當前狀態。實現的代碼如下:
int_mylocks[256];//thread'ssynchronizedarray #pragmaompparallel { int_counter0=l; int_my_id=omp_get_thread_num(); int_my_nprocs=omp_get_num_threads(); _mylocks[my_id]= 0; for (j_tile=0;j_tile0){ do{ #pragmaompflush(_mylock) }while(_mylock[myid-l]
Region Barrier
當線程遇到region barrier時會繼續執行。但是直到其他所有線程都進入這個區域之后,它才能運行出該區域。這樣的好處是允許線程繼續運行而不空轉,可以實現CPU的負載均衡。
region barrier的實現代碼如下:
unsigned_counter=0; #pragmaompparallel { {firstparallelregion} #pragmaompatomic _counter++; {barrierregion} #pragmaompflush(counter) while(counter%omp_get_num_threads()) { #pragmaompflush(counter) } #pragmaompflush {thirdparallelregion} }
當使用region barrier時,需要保證并行域R1和R3與并行域R2無依賴關系。
OpenMP SC20 Booth Talk Series : OpenMP compiler optimizations in LLVM [2]
OpenMP運行時調用重復數據的消除
double*A=malloc(size*omp_get_thread_limit()); double*B=malloc(size*omp_get_thread_limit()); #pragmaompparallel do_work(&A[omp_get_thread_num()*size]); #pragmaompparallel do_work(&B[omp_get_thread_num()*size]);
示例代碼中重復調用了omp_get_thread_limit()和omp_get_thread_num()函數,可以將重復調用合并至一次調用。該功能已在LLVM實現,可通過如下編譯選項進行優化:
$clangdeduplicate.c-g-O2-fopenmp-Rpass=openmp-opt
Tracking OpenMP Internal Control Variables
voidfoo(){ #pragmaompparallel bar(); } voidbar(){ if(omp_in_parallel()){ ... }else{ ... } }
以上代碼,如果omp_in_parallel()的返回值可以判斷為真,那么這個if結構就可以被刪除。
審核編輯:湯梓紅
-
優化
+關注
關注
0文章
220瀏覽量
23906 -
OpenMP
+關注
關注
0文章
12瀏覽量
5621 -
abstract
+關注
關注
0文章
4瀏覽量
1684
原文標題:OpenMP優化調研系列文章(1)
文章出處:【微信號:openEulercommunity,微信公眾號:openEuler】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論