[問題] 以CUDA進行矩陣連乘...

看板C_and_CPP (C/C++)作者 (藍色方舟)時間15年前 (2011/04/16 16:46), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串1/1
最近處理的程式中,我必須用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)
文章代碼(AID): #1DgLTM_T (C_and_CPP)
文章代碼(AID): #1DgLTM_T (C_and_CPP)