天天看點

CUDA——性能優化之全局記憶體

CUDA全局記憶體的合并通路(個人了解)

每個warp去通路全局記憶體,會有400-600個時鐘周期的記憶體延遲,這個代價很昂貴,是以為了減少通路全局記憶體的指令次數,我們将滿足位元組大小和對齊要求的warp合并起來通路全局記憶體,進而減少對全局記憶體的通路次數,提高GPU性能。

關于warp指令基礎知識

1)什麼是warp?

一個線程warp包括32條線程(我的電腦是1個warp包括32條線程)。它位于多處理器中。

2)warp指令

發射warp的一個指令,即該warp的32條線程一起執行的該條指令。多處理器會花費 該條指令 個時鐘周期。

3)控制流指令

任何流控制指令( if , switch , do , for , while )都會導緻warp内的線程分流,則warp要多執行該分流線程的指令,增加指令總數,花費更多的時鐘周期。為了優化性能,應減少warp内的線程分流。

4)記憶體指令

多處理器使用4個時鐘周期去發射warp的一條記憶體指令。當通路共享記憶體時,會有4個時鐘周期的記憶體延時。通路全局記憶體時,會有400-600個時鐘周期延時。

如果在等待全局記憶體通路完成期間,線程排程器可以發射足夠多的獨立算術指令,則大部分全局記憶體訪存延遲可以被隐藏掉。(即核心流水線化,邊通路,邊計算。)

5)記憶體帶寬(吞吐量)

每個記憶體空間的有效帶寬主要取決于訪存模式。

因為裝置記憶體與片上記憶體相比具有更高的延遲和更低的帶寬,是以裝置記憶體通路必須最小化,典型的程式設計模式是将來自裝置記憶體的資料存儲到共享記憶體中。

全局記憶體的合并

全局記憶體空間沒有高速緩存,是以最重要的是按照正确的通路模式獲得最大的記憶體帶寬,尤其是已知對裝置記憶體的通路有多昂貴時。

1.裝置能夠在單個指令将32位、64位、128位從全局記憶體讀取到寄存器中。

2.在執行單個讀取或寫入指令期間,每個 半warp 中同時通路全局記憶體位址的每個線程應該進行排列,以便記憶體通路可以合并到單個鄰近的、對其的記憶體通路。

(這裡我們直接使用整個warp的合并)

是以這些warp通路的首位址(WarpBaseAddress)應該對齊

32 * sizeof(type)個位元組(type為線程所通路的記憶體的資料類型。)若所通路的記憶體首位址為0,則每個warp的首位址應為32 * sizeof(type)的倍數才算是對齊,這個時候就可以将這些warp合并起來去通路全局記憶體,若有warp沒有對齊,則需要再次發射通路全局記憶體的指令,而這個指令是很昂貴的。

對于駐留在全局記憶體中的變量,其任何位址 BaseAddress 始終對齊至少256個位元組,是以為了滿足記憶體, WarpBaseAddress-BaseAddress應是32*sizeof(type)的倍數。

繼續閱讀