參考
cpu中memory<—>l3 cache傳輸頻寬為20gb/s, 除以64bytes/line得到傳輸記錄速度約300m line/s,約為300m*8= 2.4g double/s. 一般地,浮點數操作需要兩個輸入+1個輸出,那麼loading 3個數(3 lines)的代價為 100mflops。如果乙個line中的全部8個variables都被用到,那麼每秒浮點操作可以達到800mflops。而cpu工作站典型為10 gflops。這就要靠時間區域性性來重用資料了。
kepler gpu的cache line通常為128bytes(32個float or 16個double)。
資料傳輸頻寬最高250gb/s
smx的l2 cache統一1.5mb,l1 cache / shared memory有64kb
沒有cpu中的全域性快取一致性,所以幾乎沒有兩塊block更新相同的全域性陣列元素。
gpu對浮點數的操作速度可達1tflops。和上面cpu的計算類似,gpu中memory<—>l2cache傳輸頻寬為250gb/s, 除以128bytes/line得到傳輸記錄速度約2g line/s,約為2g*16= 32g double/s. 一般地,浮點數操作需要兩個輸入+1個輸出,那麼loading 3個數(3 lines)的代價為 670mflops。如果乙個line中的全部16個variables都被用到,那麼每秒浮點操作可以達到11gflops。
這樣的話每進行一次資料到device的傳輸需要45flops(45次浮點操作)才能達到500gflops. 所以很多演算法基本上不是卡在計算瓶頸,而是傳輸頻寬。
5.1 global arrays
global arrays:
儲存在/占用device memory
由host code(非kernel部分code)宣告
一直存在,直到被host code釋放
因為所有block執行順序不定,所以如果乙個block修改了乙個陣列元素,其他block就不能再對該元素進行讀寫
5.2 global variables
宣告前加識別符號device,表示變數要放在device上了 e.g.deviceint reduction_lock=0;
shared(見4.6)和constant(見4.3)中至多有乙個跟在device後面同時使用,標明用哪塊memory空間,如果這兩個都沒寫,則:
變數可以被grid內的所有threads讀寫
也可以定義為array,但是必須指定size
可以在host code中通過以下函式讀寫:
1. cudamemcpytosymbol;
2. cudamemcpyfromsymbol;
3. cudamemcpy + cudagetsymboladdress
5.4 register
預設乙個kernel中的所有內部變數都存在register中
64k 32-bit registers per smx
up to 63 registers per thread (up to 255 for k20 / k40)
這時有64k/63 = 1024個threads (256個threads for k20 / k40)
up to 2048 threads (at most 1024 per thread block)
這時每個thread有32個register
not much difference between 「fat」 and 「thin」 threads
如果程式需要更多的register呢?就「spill over」到l1 cache,這樣訪問速度就慢了,我們要盡量避免spill
5.5 local array
指kernel code中宣告的陣列。
簡單情況下,編譯器會將小陣列float a[3]轉換成3個標量registers:a0,a1,a2作處理
複雜的情況,會將array放到l1(16kb),只能放4096個32-bit的變數,如果有1024個執行緒,每個執行緒只能分配放4個變數。
5.6 shared memory
前面加識別符號sharede.g.sharedint x_dim;
要占用thread block的shared memory space.
要比global memory快很多,所以只要有機會就把global memory整成shared memory
與block同生死
thread block內所有threads共用(可讀可寫)
啥時侯用呢?當所有threads訪問都是同乙個值的時候,這樣就避免用register了
kepler gpu給l1 cache + shared memory總共64kb,可以分為16+48,32+32,48+16;這個split可以通過cudafuncsetcacheconfig()或cudadevicesetcacheconfig()設定,預設給shared memroy 48kb。這個具體情況看程式了。
參考:cuda c programming guide
different memory and variable types
cuda 安裝與配置
cuda除錯工具——cuda gdb
gpu工作方式
fermi 架構***(gpu繼承了fermi的很多架構特點)
gtx460架構
CUDA學習3 優化部分
基本概念 記憶體延遲掩藏 這裡我們假設乙個warp中線程數為2 實際不一定,如tesla為32個 有兩種規約的方式,左邊這種是採取鄰接的配對方式,右邊這種採用的是交錯的配對方式。從圖中我們可以看出,如果採用右邊這種配對方式,那麼在第一次配對完成之後我們就可以釋放出一半的warp,效能相比第一種方式有...
CUDA分支優化
標籤 cuda 分支優化 warpsm 2015 07 16 10 24 293人閱讀收藏 舉報 cuda 26 在cuda中,分支會極大的減弱效能,因為 沒有分支 因此只能讓束內線程在每個分支上都執行一遍,當然如果某個分支沒有執行緒執行,就可以忽略,因此要減少分支的數目。可以簡單的說 1.同乙個w...
CUDA 學習(二十) 優化策略5 演算法
一 概述 如果要考慮演算法,我們需要先思考如下問題 1 如何將問題分解成塊或片,然後如何將這些塊分解成執行緒 2 執行緒如何訪問資料以及產生什麼樣的記憶體模式 3 演算法總共要執行多少工作以及序列化的實現方法有何顯著不同 二 排序 可用的排序演算法有很多,其中有一些可以輕鬆 高效地在gpu 上實現,...