CUDA效能調優(一) 合併訪問 迴圈展開

2021-07-29 12:25:06 字數 2590 閱讀 1568

1  合併訪問

當同乙個warp中的所有執行緒都執行同一條指令訪問全域性儲存器中連續的單元時,就獲得最有利的訪問模式。硬體檢測到同乙個warp中的這些執行緒訪問全域性儲存器中連續的儲存單元,並將這些單元結合成乙個合併的訪問

合併訪問可以提高dram的頻寬利用率,使dram在傳輸資料時的速度接近全域性儲存器頻寬的峰值

這裡需要補充一點知識:二維三維陣列的線性對映--多維執行緒,維度對映到線性順序

二維執行緒按照線性順序排列如下圖所示:

也就是說矩陣在記憶體空間中已經被等價線性化為等價的一維陣列,以行優先的方式逐行順序存放。

示例如下:

(1)  在未使用shared memory的gpu矩陣相乘中的兩種訪問模式

接合訪問模式

在第一次迭代中,訪問0號元素,這些0號元素在global memory中相鄰,硬體接合這些訪問:

非接合訪問模式

在這個例子中得出如下結論:

對於全域性儲存器的訪問,kernel迴圈遍歷一行時,要比遍歷一列的效率低得多。

(2)  在使用shared memory的矩陣相乘中,使用合併方式載入資料

//以合併的模式載入

ds_a[ty][tx] = a[row*n+t*tile_width+tx];

ds_b[ty][tx] = b[(t*tile_width + ty)*k+col];

每個執行緒負責載入乙個md及nd元素。

m識別左側瓦片的位置。

md瓦片的一行由tile_width個執行緒載入,threadidx.x變化。

2  指令混合

在當前裝置中,每個sm的指令處理頻寬有限。每個指令占用指令處理頻寬,包括浮點計算指令、載入指令和分支指令。消除重複指令可減少指令處理頻寬的壓力,提公升kernel函式的整體執行效能。

以下面兩行**為例進行介紹:

for (int i = 0; i < tile_width; ++i)  

cvalue += ds_a[ty][i] * ds_b[i][tx]

這兩行**包括一下幾種指令:

(1)迴圈引入額外指令更新計數器k    1次

(2)每次迭代結尾位置執行條件跳轉    1次

(3)使用k計算mds,nds索引引入了位址運算指令    2次

(4)浮點乘加計算指令    2次

浮點乘加計算指令僅佔了1/3的指令。由於指令處理頻寬有限,因此這種指令混合將能取得的效能限制在頻寬峰值的1/3以內。

為了改善這用指令混合,採取迴圈展開(unroll loop)的方法。

將上面的**修改如下:

cvalue += ds_a[ty][0] * ds_b[0][tx]+ds_a[ty][1] * ds_b[1][tx]

+ds_a[ty][2] * ds_b[2][tx]+ds_a[ty][3] * ds_b[3][tx]

+ds_a[ty][4] * ds_b[4][tx]+ds_a[ty][5] * ds_b[5][tx]

+ds_a[ty][6] * ds_b[6][tx]+ds_a[ty][7] * ds_b[7][tx]

+ds_a[ty][8] * ds_b[8][tx]+ds_a[ty][9] * ds_b[9][tx]

+ds_a[ty][10] * ds_b[10][tx]+ds_a[ty][11] * ds_b[11][tx]

+ds_a[ty][12] * ds_b[12][tx]+ds_a[ty][13] * ds_b[13][tx]

+ds_a[ty][14] * ds_b[14][tx]+ds_a[ty][15] * ds_b[15][tx];

**分析:

long-multiply-add操作

消除分支指令以及loop計數器更新

索引為常量-編譯器可以使用載入指令的定址模式對應的偏移量,這樣可以消除位址運算指令。

因此,這個很長的表示式的執行速度幾乎可以接近效能的峰值。

前端效能優化一 合併css javascript

各個瀏覽器公布的資源併發數限制個數,各位看官有興趣可以自己研究下。可是有人會說這樣壓縮合併的css js不方便除錯,比如我把壓縮之後的打包檔案發上去了,發現線上出bug了怎麼辦?我推薦你用這種方案,和開發配合起來,比如後台是php,我可以在引用style min.css的時候這麼寫 if isset...

ORACLE SQL效能調優系列一

oracle的記憶體結構 sga和sql 當使用者訪問的 sql語句已經快取在 sga中,那麼該 sql就很 不用再解析 了,縮短 sql的執行時間。當使用者訪問的資料已經快取在 sga中,那麼就不用再從磁碟讀取,減少磁碟 io次數。sga越大快取的資料 包含表和索引 越多,執行的磁碟 io越少,效...

統一記憶體的效能調優

原文 為了實現統一記憶體的良好效能,必須達到以下目標 為了在不使用統一記憶體的情況下達到盡可能高的效能水平,應用程式必須引導統一記憶體驅動子系統避免上述缺陷。值得注意的是,統一記憶體驅動子系統可以檢測常見的資料訪問模式,並在沒有應用程式參與的情況下自動實現其中一些目標。但是,當資料訪問模式不明顯時,...