Question bank — CUDA programming model basics
6.2.13 · D5· Hardware › GPU Architecture › CUDA programming model basics
Yahan use hone wala har term (host, device, kernel, thread, block, grid, warp, coalescing, boundary check) parent note mein build kiya gaya hai — agar koi word unfamiliar lage, pehle wahan define karo. Related depth: Thread Warps and SIMT, Memory Hierarchy, Streaming Multiprocessors.
Pictures to lean on
Neeche teen traps geometric hain — jawab dete waqt inhe open rakho.
Teen-level hierarchy aur 2D global index kaise build hota hai (yeh "2D indexing" traps mein use hota hai):
Warps ek SM par kaise interleave hote hain — latency-hiding timeline (yeh "warp scheduling" traps mein use hota hai):
Pura memory-space map — registers, shared, constant, texture, local, global (yeh "which memory" traps mein use hota hai):
True or false — justify karo
Ek kernel launch code ko ek baar run karta hai, aur GPU usse internally loop karta hai.
Grid mein har thread shared memory ke through data share kar sakta hai.
threadIdx.x pure grid mein unique hota hai.
blockDim.x-1 tak); har block ise 0 se restart karta hai. Globally unique id hai blockIdx.x * blockDim.x + threadIdx.x.2D grid ke liye, threadIdx.x akela image mein meri row batata hai.
row = blockIdx.y*blockDim.y + threadIdx.y aur col = blockIdx.x*blockDim.x + threadIdx.x — figure s01 ka left panel dekho.Ek 2D block ek genuinely alag hardware cheez hai 1D block se.
dim3 block/grid shapes purely ek labelling convenience hain; hardware unhe phir bhi warps of 32 mein flatten karta hai. 2D/3D sirf image aur volume indexing ko readable banata hai.256 threads wala block hamesha literally ek hi instant mein sare 256 run karta hai.
Warps interleave karna GPU ko slower banata hai kyunki yeh keep switching karta hai.
Agar main elements se kam threads launch karun, toh baaki elements silently aur safely skip ho jaate hain.
cudaMalloc tumhe ek pointer deta hai jise CPU directly dereference kar sakta hai.
cudaMemcpy ke zariye PCIe bus cross karni padti hai pehle.Registers CUDA mein sabse chhoti aur sabse slow memory hain.
Constant memory har access pattern ke liye global memory se faster hai.
"Local memory" thread ke paas register ki tarah rehti hai.
Threads per block zyada use karna hamesha faster hota hai kyunki zyada parallelism.
Spot the error
int idx = threadIdx.x; multi-block launch mein global index ke roop mein use kiya.
blockIdx.x ko ignore karta hai. Har block indices 0..blockDim-1 likhega, toh sare blocks same elements stomp karenge aur array ka bada hissa kabhi touch nahi hoga.2D image kernel ke liye, int idx = blockIdx.x*blockDim.x + threadIdx.x; pixel index ke roop mein use kiya.
row*width + col, dono x aur y global indices use karke (figure s01, right panel).cudaMemcpy(h_C, d_C, bytes, cudaMemcpyHostToDevice); kernel ke baad.
cudaMemcpyDeviceToHost hona chahiye; jaise likha hai yeh GPU result ko host garbage se overwrite karta hai.numBlocks = N / threadsPerBlock; N = 1000, threadsPerBlock = 256 ke liye.
(N + tpb - 1) / tpb.Kernel body: A[idx] = idx; bina if (idx < N) ke.
A ke end ke baad likhte hain, out-of-bounds memory corruption ya crash cause karte hain.Ek grid-stride loop likha for (int i = idx; i < N; i++) ek bade array cover karne ke liye.
for (int i = idx; i < N; i += blockDim.x*gridDim.x).vectorAdd<<<numBlocks, threadsPerBlock>>>(h_A, h_B, h_C, N); host pointers pass karte hue.
d_A, d_B, d_C pass karna hai, host arrays nahi.Device memory ko free(d_A); se free karna.
free host allocations ke liye hai jo malloc se aaye hain; cudaMalloc se device memory ko cudaFree se release karna hoga.Why questions
CUDA work ko blocks mein kyun split karta hai instead of ek flat pool of threads ke?
Grid-stride loop kyun use karein jab ek plain one-thread-per-element launch already kaam karta hai?
N se decouple karta hai: ek fixed grid of, maano, 4096 threads kisi bhi size ka array process kar sakta hai kyunki har thread blockDim.x*gridDim.x aage hop karta hai, toh same launch un arrays ko bhi handle karta hai jo GPU ke thread count se bade hain.Warps ek SM par interleave kyun hote hain instead of ek ko khatam karke doosra shuru karne ke?
Constant aur texture memory offer kyun karein jab global memory sab kuch hold kar sakti hai?
Boundary check if (idx < N) kyun chahiye agar numBlocks correctly compute kiya?
numBlocks * threadsPerBlock usually N se bada hota hai, toh kuch extra threads exist karte hain aur unhe kuch nahi karne ki instruction deni hoti hai.Data device par copy kyun karein — GPU system RAM kyun nahi padh sakta?
cudaMemcpy require karta hai data ko fast device memory mein stage karne ke liye.256 threads per block prefer kyun karein, maano 30 ke bajaye?
Data move karna math karne se itna zyada costly kyun hota hai?
Thread cooperation sirf ek block ke andar kyun hoti hai, blocks ke across nahi?
Edge cases
Kya hota hai jab N, threadsPerBlock se chhota ho (jaise N = 10, tpb = 256)?
numBlocks 1 ho jaata hai, 256 threads launch hote hain; boundary check sirf threads 0–9 ko kaam karne deta hai aur baaki 246 idle baithe hain — correct, bas underutilized.Kya ho agar N, threadsPerBlock se exactly divisible ho?
N change hota hai.Kya ho agar N = 0 ho?
numBlocks = 0 deta hai, toh kernel ek empty grid ke saath launch hota hai aur simply kuch nahi karta — ek valid no-op, error nahi.Kya ho agar ek grid-stride loop N se zyada threads ke saath launch ho?
idx >= N hain woh threads kabhi loop body mein enter nahi karte — i < N condition built-in boundary check hai, toh grid-stride loops kisi bhi launch size par safe hain.Kya ho agar ek 2D block 32×32 = 1024 threads ho?
Kya ho agar do threads coordination ke bina same global address par likhte hain?
Kya ho agar ek warp ke 32 threads ek if ke alag branches lein?
Agar main cudaMalloc ka return code check karna bhool jaun aur woh fail ho, toh kya dikhta hai?
d_A ek invalid pointer rehta hai aur kernel baad mein silently memory corrupt karta hai ya crash karta hai — failure apne cause se bahut door surface karta hai, isliye har CUDA call error-check honi chahiye.Recall Jaane se pehle self-test karo
Global unique thread id formula (1D)? ::: blockIdx.x * blockDim.x + threadIdx.x.
width-wide image mein 2D pixel index? ::: (blockIdx.y*blockDim.y+threadIdx.y)*width + (blockIdx.x*blockDim.x+threadIdx.x).
Grid-stride loop stride value? ::: blockDim.x * gridDim.x — launch kiye gaye threads ki total number.
Konsa copy direction inputs GPU par load karta hai? ::: cudaMemcpyHostToDevice.
Boundary check exist kyun karta hai? ::: Ceiling division threads over-launch karta hai; check extras ko idle karta hai taaki woh out of bounds na likhein.