[問題] 以CUDA進行矩陣連乘...
最近處理的程式中,我必須用CUDA連續對上千個大小約為64*64~128*128的矩陣以及一個
64*1~128*1的向量進行乘法,而上述的計算會進行數十組,各組獨立。
(類似A*A*A*A*A.........*A*B這樣,A是矩陣B是向量,然後一次要計算幾十個這種算式)
而下面是我想到的幾個可能的平行運算方式,不知道哪一種的效率會比較好呢??
1.開啟多個BLOCK,並一起對一個矩陣乘法進行tile algrithom,如下圖
(且各組算式之間也可以用不同的BLOCK平行處理)
┌───┬───┬───┬───┐
│ BLK │ BLK │ BLK │ BLK │
│ 1 │ 2 │ 3 │ 4 │
│ 負責 │ 負責 │ 負責 │ 負責 │
├───┼───┼───┼───┤
│ │ │ │ │
│ ... │ ... │ ... │ ... │
│ │ │ │ │
├───┼───┼───┼───┤
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │
├───┼───┼───┼───┤
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │
└───┴───┴───┴───┘
可能的好處: 記憶體的重覆運用,減少GLOBAL記憶體讀取時間
可能的壞處: 由於需要進行連乘計算,跨BLOCK之間的sync不知道怎麼作會比較好
2.同一,但只單純使用一個BLOCK,各個TILE之間採sequential方式處理
可能的好處: 同樣擁有記憶體的重覆運用性,且不會有跨BLOCK之間的sync問題
可能的壞處: TILE之間的平行度會被浪費掉
3.同二,而且在算式內也進行平行處理,如:
A*A * A*A * A*A * A*A......A*B
 ̄ ̄  ̄ ̄  ̄ ̄  ̄ ̄
BLOCK BLOCK BLOCK BLOCK
1 2 3 4
並且以recursive的方式不斷的將矩陣濃縮到剩下一個
可能的好處: 拓展更多的平行度,把本來需要N個矩陣乘法時間的計算縮短成logN個矩陣
乘法時間
可能的壞處: 不比單純的array reduction,這樣作有可能會造成記憶體定址上的雜亂
(算完擺在哪裡、下一個RECURSIVE要從哪裡抓資料....)。且由於本來就
已經在不同算式間進行平行運算了,如果在加上算式內的平行運算,可能
會使一次LAUNCH的BLOCK數量衝破一萬,這樣排隊起來是不是會變得更慢?
4.從最後那個向量下手,用一個BLOCK,作A*B,作完之後產生的還是向量,便可以再跟
前一個矩陣連乘,如下圖:
┌───────────┐ ┌─┐
│ ROW1 │ │ │ Thread1進行ROW1*VECTOR的向量內積
├───────────┤ │ │ Thread2進行ROW2*VECTOR的向量內積
│ ROW2 │ │ │ Thread3進行ROW3*VECTOR的向量內積
├───────────┤ │ │ .....
│ ROW3 │ │ │
├───────────┤ X │ │
│ ROW4 │ │ │
├───────────┤ │ │ Thread64進行ROW64*VECTOR的向量內積
│ ROW5 │ │ │
├───────────┤ │ │
│ ROW6 │ │ │
└───────────┘ └─┘
A(MATRIX) B(VECTOR)
可能的好處: 由於計算出來的值只有一個VECTOR的大小,因此可以直接放在SHARE MEMORY
裡,減少每次算完都要丟回GLOBAL的記憶體成本
可能的壞處: SHARE MEMORY中可能產生嚴重的bank conflict,降低運算效率
上面是我能想到的四個演算法,不知道大家能不能給點建議或是糾正呢?謝謝!
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 130.126.107.245
※ 編輯: aobocean 來自: 130.126.107.245 (04/16 16:47)
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章