1. 程式人生 > >CUDA學習筆記(LESSON7)——常用優化策略&動態並行化

CUDA學習筆記(LESSON7)——常用優化策略&動態並行化

常用優化策略

下面讓我們來看看一些常用的優化策略,這些策略我們之前已經談過,現在只是對它進行一個總結。

資料佈局變換(Data layout transformation)

第一部分就是我們之前所說的coalescing存取模式,當相鄰執行緒訪問記憶體的相鄰位置的時候我們能獲得記憶體的最佳頻寬。所以說資料佈局的轉換實質上是重新轉換資料以獲得更好的記憶體效能。我們來看一個關於這個技術的更加複雜的例子。也就是結構陣列(AoS)與陣列結構(SoA)的效能對比。

如果我們對這兩段程式的記憶體讀取效能進行對比的話我們會發現第二段程式的效能更加好,因為DRAM存取資料的時候是以一個chunk(或burst)為單位進行操作的,陣列結構的形式可以很好地用到coalescing的技術,從而獲得更好的效能。

發散-收集變換(Scatter-to-gather transformation)

我在之前的部落格中寫過scatter與gather兩種模式的區別。如下圖所示,我們知道gather操作會存在重疊讀取的問題,但這並不會影響程式的效率;而scatter操作會導致相互衝突的寫入操作,而我們不得不用執行緒同步的技術來保證多個執行緒不會同時訪問同一個位置的記憶體。因此這一部分等待時間會降低GPU的效率。因此我們在寫程式的時候應該儘量採用gather的模式,避免scatter的模式。

平鋪(Tiling)

很多時候我們需要頻繁訪問某一段記憶體,在CPU中,我們可以將這部分資料庫做隱式拷貝,放入快取中,來獲得更高的訪問速度。然而隱式拷貝不適合我們的GPU,因為我們擁有大量的執行緒,因此每個執行緒對應的快取將非常少。因此我們在GPU中採用的是顯示拷貝的技術,它讓我們人工地去為每一個block中的執行緒分配一個快取,這部分快取中的資料能被一個block中的所有執行緒共用,這部分快取也就是我們之前講的shared memory。

下面讓我們來看一個例子。

對於以上兩段程式碼都能;利用coalescing技術來獲得很好的存取效能,但是第一段程式碼中A、B、C、D、E五個陣列中每個資料只會訪問一次,而第二段程式碼中in中的資料的資料卻會被多次訪問,因此我們可以將它放在shared memory中,從而獲得更高的訪問速度。

私有化(Privatization)