CUDA程序性能调优
目錄
1、kernel function parameters
2、?local variables
4、device function calls
5、loop/if
參考文獻:CUDA程序調優指南(二):性能調優 - 知乎
介紹了GPU的結構以及資源的控制要素(GPU硬件結構和程序具體參數設置_yu132563的專欄-CSDN博客),下面就可以對CUDA進行程序的調優,從而在不同的GPU上面運行同一個CUDA程序的參數設置方法。
對于一個CUDA kernel function而言,其通常由如下幾個部分組成:
- kernel function paras
- local variables
- shared memory with __syncthreads__ call
- device function call
- loop/if
- <<<BlocksNum, ThreadsNumPerBlock>>>
我們分別考慮如何對這些部分進行優化。
1、kernel function parameters
__global__?function的參數是存在constant mem里的,并且其大小被限制為4KB。通常來說,我們傳入的參數都比較少,因此這些參數大部分是直接緩存在SM上的register上的,因此讀取起來最快。但如果register不夠用,那么就會被放到constant mem/cache上,速度就會變慢。
2、?local variables
對于單獨的local var,其會被放在register里面,因此讀寫極快。對于數組類型的local var,根據訪問pattern的不同,速度也不同(見per-thread array的訪問)。總結而言是這樣的:
- 【Static Indexing】:會被放到register里,讀寫極快
- 【Dynamic indexing with Uniform Access】:會被放到Local Mem里,略慢。但?更高的math/load比?配合?緩存到L1/L2cache里,也可以很快
- 【Dynamic indexing with Non-uniform Access】:由于會讓SM產生多個訪存指令,所以最慢。 但可以通過把其放到shared mem里加速
3、shared memory with?__syncthreads__?call
shared memory需要盡量避免bank confilicts,這樣讀取最快,一個cycle clock就可以讀取128byte。除此之外,因為shared memory由同一block內的thread共享,所以在初始化shared mem之后,需要調用__syncthreads__來對同一block內的所有threads進行同步。
4、device function calls
編譯器會自行決定device function是否會被inlined(多數情況下會inline)。通常來說,inline會更好,因為少了函數調用的開銷。
5、loop/if
在書寫kernel function時,應盡量避免loop/if,因為這兩個在代碼里引入了分支結構。
如果代碼有分支,那么
因此在可能的情況下,我們應該盡量使用模板參數來替換掉loop/if:
- 如果if所判斷的條件在kernel launch時就能確定(即作為kernel的一個parameter傳入的),那就可以用模板參數來代替該parameter,這樣編譯器會自動優化掉另一分支。
- 同理,如果for-loop的邊界也在kernel launch時就能確定,那也可用模板參數代替。
針對一些邊界是常量(如0->5)的循環,在循環體足夠簡單的情況下,可以使用#pragma unroll來告訴編譯器展開該循環。
參考文獻:CUDA程序調優指南(二):性能調優 - 知乎
總結
以上是生活随笔為你收集整理的CUDA程序性能调优的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2018广技师C语言专插本试题,2018
- 下一篇: 计算机数据结构英语作文,数据结构学习心得