Exercises — CUDA programming model basics
6.2.13 · D4· Hardware › GPU Architecture › CUDA programming model basics
Shuru karne se pehle, ek formula jis par poora page tika hai usse pakka kar lete hain, kyunki isme har symbol ko samajhna zaroori hai.
Figure dekho: crate , seat , lockers per crate ke saath, locker par land karta hai.

L1 — Recognition
Exercise 1.1 (L1)
Har term ko uski jagah se match karo. Host, Device, Kernel, Warp ke liye ek phrase mein batao yeh kya hai.
Recall Solution
- Host ::: CPU aur uski system RAM — jahan
main()run karta hai. - Device ::: GPU aur uski VRAM — jahan kernels run karte hain.
- Kernel ::: ek
__global__function jo host se launch hota hai lekin device par bahut saare threads ke saath ek saath execute hota hai. - Warp ::: threads ka ek hardware bundle jo instructions ko lockstep (SIMT) mein execute karta hai. Dekho Thread Warps and SIMT.
Exercise 1.2 (L1)
vectorAdd<<<numBlocks, threadsPerBlock>>>(...) mein, donon triple-angle numbers mein se kaun sa grid size hai aur kaun sa block size?
Recall Solution
- Pehla number,
numBlocks::: grid size — kitne blocks hain. - Doosra number,
threadsPerBlock::: block size — har block mein kitne threads hain. Toh logical order hai Grid → Blocks → Threads, bilkul waisi hi order jisme yeh appear karte hain.
Exercise 1.3 (L1)
Inhe fastest→slowest order mein lagao: Global Memory, Registers, Shared Memory, Host Memory.
Recall Solution
Registers ( cycle) → Shared Memory ( cycles) → Global Memory ( cycles) → Host Memory ( cycles). Compute cores ke jitna paas = utne kam wires cross karne padte hain = utna fast. Dekho Memory Hierarchy.
L2 — Application
Exercise 2.1 (L2)
Ek thread ka blockIdx.x = 3, blockDim.x = 256, threadIdx.x = 17 hai. Uska globalIdx compute karo.
Recall Solution
Humne kya kiya: crates mein threads count kiye, phir apni seat add ki.
Exercise 2.2 (L2)
Tumhare paas elements hain aur tum choose karte ho. Kitne blocks launch karoge?
Recall Solution
Ceiling division use karo taaki koi element cover hone se na reh jaye: Check: . Theek hai — kuch spare threads hain, jinhe boundary check handle karta hai.
Exercise 2.3 (L2)
width = 640 ki ek D image ke liye, ek thread row = 5, col = 12 compute karta hai. Row-major array mein uska flattened globalIdx kya hoga?
Recall Solution
Row-major ka matlab hai: agli row shuru karne se pehle har completed row ko poora cross karo.
L3 — Analysis
Exercise 3.1 (L3)
aur ke saath, exactly kitne threads launch hote hain, aur if (idx < N) ki wajah se kitne threads idle hain (jo koi kaam nahi karte)?
Recall Solution
. Total threads launched .
Working threads = jinke hai, yaani unme se .
Idle threads (indices se tak). Yeh if test ko false pass karte hain aur simply exit kar jaate hain.
Exercise 3.2 (L3)
Figure dekho. Tail crate sirf partly use ho rahi hai. Explain karo kyun vectorAdd kernel se if (idx < N) hatana dangerous hai, aur ke liye kaun sa thread sabse pehle misbehave karta hai.

Recall Solution
Threads poore blocks mein aate hain; tum "exactly " launch nahi kar sakte. Last block index tak overshoot karta hai. Guard ke bina, thread A[1000]/B[1000] read karega aur C[1000] write karega — array ke end se ek element aage (valid indices par ruk jaate hain). Yeh out-of-bounds access hai: crash ya corrupted neighbouring memory. Pehla offender hai.
Exercise 3.3 (L3)
Ek math op cycle cost karta hai; ek global memory read cycles cost karta hai. Naïve vectorAdd mein, har output ko global reads + global write + add chahiye. Actual arithmetic par roughly kitna fraction of time spend hota hai?
Recall Solution
Memory cycles . Arithmetic cycle. Interpretation: vectorAdd bilkul memory-bound hai — GPU apna time data move karne mein spend karta hai. Isliye Memory Hierarchy aur coalescing raw FLOPs se zyada matter karte hain yahan.
L4 — Synthesis
Exercise 4.1 (L4)
Ek kernel scaleAdd likho jo compute kare (ek "SAXPY") proper index aur boundary check ke saath. , ke liye launch config batao.
Recall Solution
__global__ void scaleAdd(float a, float *A, float *B, float *C, int N) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < N) {
C[idx] = a * A[idx] + B[idx];
}
}Launch:
Check: . Call: scaleAdd<<<1954,256>>>(a,d_A,d_B,d_C,N);
Exercise 4.2 (L4)
Kisi bhi kernel ko device data par run karne ke liye zaroori chhe host-side steps (order mein) list karo, aur input aur output copies ke liye correct cudaMemcpy direction enum do.
Recall Solution
- Host memory allocate karo (
malloc). - Device memory allocate karo (
cudaMalloc). - Inputs Host→Device copy karo — enum
cudaMemcpyHostToDevice. - Kernel
<<<numBlocks, threadsPerBlock>>>launch karo. - Results Device→Host copy karo — enum
cudaMemcpyDeviceToHost. - Device (
cudaFree) aur host (free) memory free karo.
Exercise 4.3 (L4)
image (width=640, height=480) par D kernel ke liye block dims ke saath, grid dimensions (gridX, gridY) compute karo.
Recall Solution
Total blocks ; total threads , jo pixels se exactly match karta hai (yahan koi idle threads nahi kyunki dono dims evenly divide hote hain).
L5 — Mastery
Exercise 5.1 (L5)
Ek kernel grid blocks, block threads ke saath launch hota hai. Jo thread array index process karne wala hai — uske blockIdx.x aur threadIdx.x kya hain?
Recall Solution
Index formula ko invert karo. Block size se divide karo: , toh . Forward verify karo: . ✓
Exercise 5.2 (L5)
Maano global memory se read karna cycles cost karta hai lekin shared memory se cycles. Ek tiling kernel har element ko global memory se ek baar shared memory mein load karta hai, phir usse shared memory se baar reuse karta hai. Naïve kernel ke against total memory cycles per element compare karo jo global memory baar read karta hai.
Recall Solution
- Naïve: global reads cycles.
- Tiled: global read shared reads cycles.
- Speedup . Isliye exactly shared memory exist karti hai: expensive off-chip trip ek baar pay karo, phir saste mein reuse karo. Dekho Memory Hierarchy aur Streaming Multiprocessors.
Exercise 5.3 (L5)
Ek GPU ke paas SMs hain aur maximum resident blocks per SM hold kar sakta hai. Tum blocks ka ek grid launch karte ho. Kya saare blocks ek saath resident hain? Agar nahi, toh GPU ko kitne "waves" of blocks ki zaroorat hai?
Recall Solution
Max simultaneously resident blocks . Kyunki hai, saare ek saath fit nahi hote. Number of waves: Actually . GPU blocks ko waves mein process karta hai; scheduler finished blocks retire karta hai aur waiting wale swap in karta hai. Yahi cheez ek kernel ko code change kiye bina ek small GPU se huge GPU tak scale karne deti hai.
Recall Quick self-test recap
N=1000, tpb=256 ke liye ceiling block count ::: blocks, idle threads.
Block 3, blockDim 256, thread 17 ke liye global index ::: .
if (idx < N) kyun ::: last block array ko overshoot karta hai; guard out-of-bounds access rokta hai.
Fastest CUDA memory ::: registers ( cycle), on-chip, compute unit mein.