讓我說,我讀過關於SO仔細閱讀所有類似的問題開始:CUDA估計每塊和塊編號線程2D網格數據
- Determining threads per block and block per grid
- Threads per SM, threads per block
- CUDA Blocks and Threads
- Warps and optimal number of blocks
我的意圖是嘗試和計算dynami爲我正在開發的前饋神經網絡庫提供(而不是硬編碼值)。
我的數據不是正方形格子(矩陣狀),這是常有與我見過最實施例中,它是不是兩個矢量產生的矩陣,具有不相等的行列:
float x[6] {1.f, 1.f, 0.f, 1.f, 1.f, 0.f};
thrust::device_vector<float> in_vec(x, x+6);
float y[9] {1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f};
thrust::device_vector<float> w_vec(y, y+9);
thrust::device_vector<float> o_wec(9);
thrust::device_vector<float> mtx_vec(9 * 6);
float * i_ptr = thrust::raw_pointer_cast(in_vec.data());
float * w_ptr = thrust::raw_pointer_cast(w_vec.data());
float * out_ptr = thrust::raw_pointer_cast(mtx_vec.data());
dim3 threadsPerBlock(9,6);
dim3 numBlocks(1,1);
prop_mtx<<<numBlocks,threadsPerBlock>>>(w_ptr, i_ptr, out_ptr, 6);
和內核:
__global__ void prop_mtx(float * w, float * i, float * o, int s)
{
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
o[y + x * s] = w[x] * i[y];
}
爲什麼我已經採取了這種做法,因爲它使神經網絡計算的意義,當它涉及到向量/矩陣計算的原因。 我想保持這個一致性,並且使用用於權重*輸入計算的2D網格的AFAIK是合理的。
我必須將每個塊的線程計算爲2D,並且網格中的線程數量不等。
我尤斯一個GTX 660,其中有:
CUDA Capability Major/Minor version number: 3.0
Total amount of global memory: 2047 MBytes
(5) Multiprocessors, (192) CUDA Cores/MP: 960 CUDA Cores
Maximum Texture Dimension Size (x,y,z) 1D=(65536), 2D=(65536, 65536), 3D=(4096, 4096, 4096)
Warp size: 32
Maximum number of threads per multiprocessor: 2048
Maximum number of threads per block: 1024
Max dimension size of a thread block (x,y,z): (1024, 1024, 64)
Max dimension size of a grid size (x,y,z): (2147483647, 65535, 65535)
我想明白,我怎麼可以推斷/計算網格尺寸,每塊的線程和塊的數量。
讓我們假設我有一個800個項目的權重向量和一個6500個項目的輸入向量。
- 這是否意味着我真正需要的是一個800,6500的二維網格?據我所知,其他的都會提供不正確的結果?
我知道我的最大線程每塊爲1024,但由於其在2D網格,它更可能是:
dim3 threadPerBlock(X,Y);
由於事實上,我的網格不是一個方形矩陣,我需要以不同的方式計算每個塊的X,Y線程?
或者我需要先推斷出所需的塊數?
- 是否最小網格大小,而不管所有其它參數需要爲至少32 ,還是32的倍數?我是否需要至少每塊32個線程,或最小數目爲32的網格大小?
最後,由於我的螺紋經大小爲32,
任何僞代碼,或解釋我應該如何去做,將不勝感激。
我試過的是計算我的2D網格大小,通過將我的數據除以32包裝大小。 然後我考慮使用可用的SM計算網格線程。例如
800 weights/5 SM, = 160 x's per SM
6500 inputs/5 SM, = 1300 y's per SM
但我不知道該從那裏做什麼。 最後,我認爲首先找到輸入重量比:
6500/800 = 8.125
言下之意是使用X的32最小網格大小, ÿ將不得不由8.125 * 32 因此相乘,我的threadsPerBlock將是:
dim3 threadsPerBlock(32,260);
那當然,每塊有8320個線程,遠遠超過每塊1024個。
所以這是我的問題:我怎麼不超過每塊1024線程,同時保留我的數據正確的網格大小?
PS:我的問題不是優化代碼,而是瞭解如何在設備上分配線程和網格數據。
http://stackoverflow.com/questions/9985912/how-do-i-choose-grid-and-block-dimensions-for-cuda-kernels/9986748#9986748 – talonmies
@talonmies雖然你的答覆是非常有幫助的,它並沒有回答我的所有問題:我如何推斷線程數量(總數?),以便網格與數據對齊,還是不需要對齊? 其中一個答案有以下幾種:gridSize =(N + blockSize - 1)/ blockSize; 我是否需要計算每個塊的線程,而不管網格X,Y? –
是的,選擇一個任意塊大小,如32x32。然後用x-block-dimension(32)除以總的x-柵格寬度(800),並在網格的x方向上啓動許多塊(加上一個)。然後用y方塊尺寸(32)除以y方格寬度(6500),然後在網格y方向上啓動多個方塊(加1)。 GPU中SM的數量不包括在內。我會假設,就像在你的微不足道的情況下,你需要9x6線程,在更大的情況下,你將需要800x6500線程。這種方法在許多地方都有涉及。 –