多面體模型的基本概念
編譯器中的多面體模型(polyhedral model)是一種高效的程序優化技術,它將復雜的循環依賴關系映射到高維幾何空間,從而在編譯階段實現對計算任務的并行化和局部性優化。
通過構建和操作多面體表示能有效地調度指令和數據訪問,以減少資源爭用和緩存未命中德情況,從而提高程序執行的性能。
本文將介紹多面體編譯技術的理論基礎,并以發掘循環可并行部分為例子講解。
將循環表示為線性不等式
首先我們來看一個常規的循環:
for(inti=1;ifor(intj=1;j
我們先不關注循環內執行什么語句,而是關注迭代空間 i
和 j
以及迭代限制條件:
i>=1
i=1
j
轉換為等價形式:
i>=1
i<=?N?-?1
j>=1
j<=?N?-?1
再統一轉換為 >= 0
約束:
i-1>=0
-i+N-1>=0
j-1>=0
-j+N-1>=0
這樣就將循環迭代空間表示成了一組線性不等式,然后矩陣形式表達如下:
這一組線性不等式其實就定義了二維空間上的一個矩形:
我們再來看一個例子,
for(inti=1;ifor(intj=1;jif(i<=?N?-?j?+?1)
S[i][j]=....
這個循環相比上面的循環就是多了一個約束條件 i <= N - j + 1
也就是 j <= -i + N + 1
,也就是在上面坐標軸上再加一條線:
這樣就很清楚了,這些約束的交集對應了二維空間上的一個多面體(polyhedron),同理可得如果是三層循環空間,那就是對應了三維空間上的一個多面體,每個約束條件對應一個二維平面,而在 n 維空間上就是一個超平面了。
數據依賴距離向量的定義
接著我們來介紹怎么分析循環中的數據依賴,多面體模型中的數據依賴描述了在循環結構中,不同迭代之間因數據訪問而產生的依賴關系。
而對于循環嵌套內的依賴關系,可以用距離向量來描述相對執行順序。
比如對于以下循環:
for(inti=1;ifor(intj=1;j-1][j]+A[i][j-1];
在當前次 (i
和 j
) 迭代中需要往 A[i][j]
中寫入數據,然后需要讀取 A[i-1][j]
和 A[i][j-1]
的內容也就是循環維度 i
和 j
的前一次迭代 i-1
和 j-1
需要寫入的位置,所以這就引入了一個先寫然后再讀取的數據依賴。
然后我們定義距離向量如下,向量的值大小表示了在對應循環維度上依賴的上一次迭代的距離:
-
A[i][j] -> A[i-1][j]
的距離向量為[i - (i -1 ), j - j] = [1, 0]
-
A[i][j] -> A[i][j-1]
的距離向量為[i - i, j - (j - 1)] = [0, 1]
矩陣形式表示:
能否簡單從距離向量看出循環能否并行呢?
以下討論均假設循環都是正向且迭代步長均為1,且迭代空間為常規的整數,且不保證結論能推廣。
對于該循環
for(inti=1;ifor(intj=1;j-1][j]+A[i][j-1];
其距離向量為:
分析第一行可以看到i
循環維度的上,依賴了前一次迭代的計算值,所以可以知道在 i
循環上無法并行。
而分析第二行依賴,j
循環維度也依賴了前一次迭代的計算值,所以可以知道在 j
循環上也無法并行。
又比如對于循環
for(inti=1;ifor(intj=1;j0;
其距離向量為 [0]
。
循環維度 i
和 j
對于前面的循環沒有任何依賴,所以能將兩個循環合并為一個然后并行運行。
又比如對于循環
for(inti=1;ifor(intj=1;j-1];
其距離向量為 [0, 1]
。循環維度 i
無依賴可以在該維度上并行,但是在 j
維度上有依賴無法并行。
又比如對于循環
for(inti=1;ifor(intj=1;j-1][j]+A[i-1][j-1];
其距離向量為:
兩個依賴的循環維度 i
都是大于0,所以在 i
維度無法循環,但是在 j
維度卻可以并行。所以只要第一列都大于0,則不用分析第二維了,第二維是一定可以并行的。
有些循環的距離向量沒法直接看出來,比如經典的矩陣乘法:
for(inti=0;ifor(intj=0;jfor(intk=0;k
這里在循環維度 k
上有個隱式的依賴,當前迭代(i', j', k')
的 C[i'][j']
計算依賴于上一次迭代 (i', j', k'-1)
計算得到的 C[i'][j']
,所以距離向量為 [0, 0, k-(k'-1)=1]
,所以在k
維度上無法并行。
對循環做變換
多面體模型中對循環優化是通過對循環迭代空間做仿射變換實現的,下面我們介紹三種簡單的變換,交換和傾斜。
以二層循環為例:
for(inti=1;i<=?2;++i)
for(intj=1;j<=?3;++j)
S[i][j]=...
對應的每一次迭代的執行順序如下圖,圖中的圓型就對應每一次的迭代,序號就是原始執行順序:
假設變換后的循環維度分別是 i'
和 j'
。
循環交換
對應的變換矩陣如下:
變換過程如下:
對應的循環就變為:
for(intj=1;j<=?3;++j)
for(inti=1;i<=?2;++i)
S[i][j]=...
對應的迭代執行順序如下:
圖中圓型的序號為變換前的原始執行順序。
第一個執行的坐標是 (i'=1, j'=1)
,對應原始坐標是 (i=1, j=1)
,對應圓型 1
。
第二個執行的坐標是 (i'=1, j'=2)
,對應原始坐標是 (i=2, j=1)
,對應圓型 4
。
第三個執行的坐標是 (i'=2, j'=1)
,對應原始坐標是 (i=1, j=2)
,對應圓型 2
。
其他以此類推
循環反轉
對應的變換矩陣如下,假設就對循環 i
做反轉:
變換過程如下:
對應的循環就變為:
for(inti=-1;i>=-2;--i)
for(intj=1;j<=?3;++j)
S[i+3][j]=...
對應的迭代執行順序如下:
圖中圓型的序號為變換前的原始執行順序。
第1個迭代 (i'=-1, j'=1)
對應原始坐標 (i=2, j=1)
,對應原始循環的圓型 4
。
第4個迭代 (i'=-2, j'=1)
對應原始坐標 (i=1, j=1)
,對應原始循環圓型 1
。
循環傾斜
對應的變換矩陣如下:
變換過程如下:
對應的循環就變為:
for(intd=2;d<=?5;++d)
for(intj=max(1,d-2);j<=?min(3,d-1);++j)
inti=d-j;
S[i][j]=...
對應的迭代執行順序如下:
圖中圓型的序號為變換前的原始執行順序。
第1個迭代 (d=2, j=1)
對應原始坐標 (i=1, j=1)
,對應原始循環的圓型 1
。
第2個迭代 (d=3, j=1)
對應原始坐標 (i=2, j=1)
,對應原始循環圓型 4
。
第3個迭代 (d=3, j=2)
對應原始坐標 (i=1, j=2)
,對應原始循環圓型 2
。
第4個迭代 (d=4, j=2)
對應原始坐標 (i=2, j=2)
,對應原始循環圓型 5
。
第5個迭代 (d=4, j=3)
對應原始坐標 (i=1, j=3)
,對應原始循環圓型 3
。
第6個迭代 (d=5, j=3)
對應原始坐標 (i=2, j=3)
,對應原始循環圓型 6
。
如何將串行執行的循環轉換為可并行執行
以下面的循環為例:
for(inti=1;i<=?N;?i++)?{
????for(intj=1;j<=?N;?j++)?{
????????A[i][j]?=?A[i-1][j]+A[i][j-1];
}
}
分析上其數據依賴分析可得其距離向量:
可知該循環在 i
和 j
維度上都無法并行執行。
接下來嘗試對循環空間 i
和 j
做仿射變換,我們采用傾斜變換,其實這個是很經典的一個并行方法了,稱之為對角線變換。
具體到多面體編譯技術的代碼的實現,是怎么自動找到這個變換的過程我還沒完全弄懂,所以假設我們現在知道了是直接應用傾斜變換:
代碼變為:
for(intd=2;d<=?2*N;++d){
for(intj=max(1,d-N);j<=?min(N,?d?-?1);++j){
inti=d-j;
A[i][j]=A[i-1][j]+A[i][j-1];
}
}
接著分析數據依賴矩陣,這時候 A[i][j]= A[d-j][j]
的計算都只依賴于循環 d
前一次迭代的計算而循環 j
維度上沒有數據依賴,所以依賴矩陣為:
從依賴矩陣可知,變換后的循環可以在 j
循環維度上做循環。
上面的文字解釋可能有些抽象我們畫圖來輔助解釋,假設循環上界 N=5
,則原始的循環迭代空間如下圖所示:
黑色實線箭頭表示每個計算 A[i][j]
的計算順序。
數據依賴關系如下:
紅色箭頭表示數據依賴。
則經過傾斜變換后的循環迭代空間如下:
for(intd=2;d<=?2*5;++d){
for(intj=max(1,d-5);j<=?min(5,d-1);++j){
inti=d-j;
A[i][j]=A[i-1][j]+A[i][j-1];
}
}
其實就是對應于原始空間上,按照對角線的順序去遍歷。
數據依賴如下:
從數據依賴上看,可以看到變換后在 j
維度上沒有數據依賴所以可以并行執行。
最后在 j
維度上加上 omp
并行:
for(intd=2;d<=?2*5;++d){
#pragmaompfor
for(intj=max(1,d-5);j<=?min(5,d-1);++j){
inti=d-j;
A[i][j]=A[i-1][j]+A[i][j-1];
}
}
后記
這篇文章中對于多面體模型有并不少是個人理解,不一定準確。多面體編譯技術個人感覺很復雜,在閱讀相關文獻和書籍的時候,還需要去搜過相關前置知識才能看懂大概。
而這篇學習筆記也僅僅是介紹了一些基本的入門概念,多面體編譯技術能做的事情并不僅僅局限于本文所介紹的循環變換發掘可并行部分,感興趣的讀者可以閱讀參考資料。
審核編輯 :李倩
-
線性
+關注
關注
0文章
199瀏覽量
25175 -
模型
+關注
關注
1文章
3279瀏覽量
48976 -
編譯
+關注
關注
0文章
661瀏覽量
32939
原文標題:參考資料
文章出處:【微信號:GiantPandaCV,微信公眾號:GiantPandaCV】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論