Exercises — CUDA cores and execution model
6.2.3 · D4· Hardware › GPU Architecture › CUDA cores and execution model
Parent note: CUDA cores and execution model. Prerequisites jo tumhare paas open ho sakti hain: 6.2.01-GPU-vs-CPU-architecture, 6.2.02-GPU-memory-hierarchy, 6.1.03-SIMD-vs-SIMT, 6.2.04-occupancy-and-performance.
Shuru karne se pehle, vocabulary ke teen chhote pieces jo poora page inhi par tikaa hai, bilkul zero se banaye gaye hain:
Level 1 — Recognition
Exercise 1.1. Ek warp mein kitne threads hote hain, aur unke liye "in lockstep" ka kya matlab hai?
Recall Solution 1.1
Ek warp mein 32 threads hote hain. "In lockstep" ka matlab hai ki saare 32 same cycle par same instruction execute karte hain — jaise 32 dancers jo kabhi bhi alag move nahi kar sakte, hamesha ek hi move karte hain. Woh sirf us data mein alag hote hain jo har ek apne registers mein rakhta hai, kabhi us instruction mein nahin jo ek given tick par run karte hain.
Exercise 1.2. Sach ya jhooth: ek CUDA core ek poora processor hai jaise CPU core, jiske paas apna branch predictor aur instruction decoder hota hai.
Recall Solution 1.2
Jhooth. Ek CUDA core sirf ek ALU (arithmetic logic unit) hai — ek chhota calculator jo ek cycle mein ek FP32 ya integer operation karta hai. Iske paas koi private decoder, branch predictor, ya independent instruction stream nahin hoti. Woh apne warp ke baaki 31 cores ke saath saara control logic share karta hai. Yahi sharing ki wajah se GPUs per-ALU saste hain lekin branchy code mein bure hain.
Exercise 1.3. Architecture hierarchy ke char levels ke naam batao, sabse chhote se sabse bade tak.
Recall Solution 1.3
- CUDA core (ek scalar ALU, 1 op/cycle)
- Warp (32 threads in lockstep)
- Streaming Multiprocessor (SM) (kai cores + schedulers + registers + shared memory rakhta hai)
- GPU chip (kai SMs rakhta hai)
Level 2 — Application
Exercise 2.1. Ek grid blockDim.x = 256 ke saath launch hua hai. Block blockIdx.x = 7 mein position threadIdx.x = 40 wale thread ka global thread ID compute karo.
Recall Solution 2.1
Indexing formula use karo:
Har piece ka matlab: blockIdx.x hai kaun sa block (kaun sa platoon), blockDim.x hai threads per block (platoon size), aur threadIdx.x hai tumhara seat apne block ke andar. Block index ko block size se multiply karne par saare pehle platoons skip ho jaate hain; apna seat add karne par tum exactly land karte ho.
Exercise 2.2. Tumhare paas N = 1{,}000{,}000 elements hain aur tumne threadsPerBlock = 256 choose kiya. Standard ceiling launch formula use karke, kitne blocks launch karoge?
Recall Solution 2.2
Formula upar round karta hai (yahi floor bracket hai jo ek number ko next whole value se aage nudge karne par apply hota hai) taaki koi element uncovered na rahe:
+ threadsPerBlock - 1 kyun? Plain integer division neeche round karta hai, jisse aakhri partly-full block drop ho jaata. Pehle ek-se-kam-ek-block add karna kisi bhi remainder ke hote hue round-up force karta hai — ye exactly disguise mein ceiling hai.
Yeh threads launch karta hai — extra threads kernel mein if (i < N) guard se band ho jaate hain.
Exercise 2.3. Ek block mein 256 threads hain. Kitne warps hain? Agar block mein 250 threads hain toh?
Recall Solution 2.3
Warps 32 ke chunks mein bante hain, isliye thread count ko ceiling bracket se upar round karte hain:
- warps exactly. Clean.
- warps. 8th warp mein sirf threads hain; baaki lanes inactive hain lekin warp slot occupy karte hain. Dono cases mein poore warp ki keemat chukani padti hai.
Level 3 — Analysis
Exercise 3.1. Ek SM mein 128 CUDA cores hain. Ek student claim karta hai "32 threads ka ek warp isliye cycle mein khatam ho jaata hai." Error diagnose karo aur ek warp instruction ki sahi minimum latency batao.
Recall Solution 3.1
Sahi minimum 1 cycle hai, quarter cycle nahin.
Student galat kyun hai: ek warp instruction per issue atomic hoti hai — scheduler jo sabse chhota time slice deal mein leta hai woh ek cycle hai. 128 cores hone se woh cycle pieces mein nahin katata.

Figure mein kya observe karo: grid SM ke saare 128 cores ek single tick par dikhata hai. 32 magenta squares woh lanes hain jo is ek warp ko run kar rahi hain — woh us tick par ek saath light up hoti hain aur khatam hoti hain. 96 pale squares is warp ke liye idle hain, lekin orange label yaad dilata hai ki woh kisi doosre warp ko same tick par run karne ke liye free hain. Toh picture point ko visual banati hai: extra cores SM ko sideways wide karte hain (zyada warps ek saath), woh kabhi bhi is ek warp ki single tick ko chhoti nahin karte.
Extra cores ka asli faayda throughput hai, latency kam karna nahin: 128 cores aur multiple schedulers ke saath, SM same cycle mein kai warp-instructions issue kar sakta hai (different warps se), saare 128 cores ko busy rakhta hai — lekin har individual warp ko phir bhi kam se kam ek cycle lagti hai.
Exercise 3.2. Ek warp ke 32 threads mein se har ek ek float (4 bytes) read karta hai. Case A mein woh A[0..31] (consecutive) read karte hain. Case B mein thread A[i*32] (stride 32) read karta hai. 128-byte transactions use karke har ke liye transaction efficiency compute karo.
Recall Solution 3.2
Efficiency hai bytes jo tumhe chahiye ÷ bytes hardware ne move kiye: Dono cases mein useful bytes .
Case A (coalesced): saare 32 consecutive floats exactly bytes = ek aligned transaction span karte hain. Case B (stride 32): consecutive threads bytes apart land karte hain, isliye har thread ka float apni khud ki 128-byte line mein hota hai → 32 alag transactions. Case B same useful data ke liye zyada bytes move karta hai — yahi woh " slower" hai jiske baare mein tumhe warn kiya gaya tha.

Figure mein kya observe karo: top row (magenta bracket) coalesced case hai — 32 requested floats side by side hain aur ek magenta box dikhata hai ki woh sab ek 128-byte transaction mein fit ho jaate hain, toh koi byte waste nahin. Bottom row (orange) strided case hai — sirf har 8th cell woh float hai jo hume actually chahiye (orange cells), aur har ek apne khud ke transaction box mein wrapped hai, toh hardware same 128 useful bytes deliver karne ke liye 32 full lines kheechta hai. Aankhein instantly dekh leti hain kyun top kuch waste nahin karta aur bottom almost sab waste karta hai.
Exercise 3.3. Registers per SM cap par hai. Tum resident threads chahte ho. Rough per-thread register ceiling kya hai? Agar tumhara kernel actually 64 registers/thread use karta hai toh occupancy ka kya hoga?
Recall Solution 3.3
Ceiling hai total budget evenly split: Agar kernel ko sach mein 64 registers/thread chahiye, toh tum sirf resident rakh sakte ho — aadhe threads. Kam resident threads matlab latency hide karne ke liye kam warps, toh occupancy drop hoti hai. (Yeh exactly woh hinge hai jo 6.2.04-occupancy-and-performance mein jaata hai.)
Level 4 — Synthesis
Exercise 4.1. Ek SM mein warp schedulers hain. Har resident warp cycles useful compute karta hai, phir global-memory read par cycles stall karta hai. Latency poori tarah hide karne ke liye kitne resident warps chahiye? Agar SM 64 resident warps par cap kare, toh kya full hiding possible hai?
Recall Solution 4.1
Bookkeeping banao. Ek warp ke stall cycles ke dauran, SM ke schedulers doosre kaam ke warp-instructions issue kar sakte hain. Har warp stall hone se pehle sirf instructions supply karta hai, isliye pipeline fed rakhne ke liye needed warps ki sankhya hai: SM 64 resident warps par cap karta hai. Kyunki , is kernel ke liye full latency hiding impossible hai is SM par. ALUs kuch time idle baithenge — kernel memory-bound hai.
Exercise 4.2. Same SM ke liye (, , cap warps), minimum compute intensity kya hai jo full latency hiding possible banata hai?
Recall Solution 4.2
set karo aur solve karo: Kyunki poore instructions count karta hai, tumhe cycles compute per stall chahiye. Design meaning: compute per memory op badhane se — kaam fuse karna, registers/shared memory se values reuse karna (dekho 6.2.02-GPU-memory-hierarchy), ya 7.3.01-parallel-programming-patterns mein tiling patterns — tum ko itna kam kar sakte ho ki 64 warps kaafi ho jaayein.
Exercise 4.3. Tumhe N = 1{,}000{,}000 floats ke do vectors add karne hain. threadsPerBlock aur numBlocks choose karo, batao warps per block kitne hain, aur explain karo kyun 256 ek safer default hai 1000 se.
Recall Solution 4.3
threadsPerBlock = 256 choose karo (32 ka multiple) taaki koi warp partly empty na ho:
Blocks needed (ceiling, kyunki ek partial block bhi count hoti hai):
1000 threads/block kyun nahin? 32 ka multiple nahin hai: warps, aur aakhri warp sirf active lanes run karta hai 32 mein se — har block mein 24 lanes waste. Saath hi 1000, 1024 hard cap ke paas hai, register pressure ke liye koi headroom nahin. 32 ka round multiple (128, 256, 512) warps full rakhta hai aur occupancy tuning flexible.
Level 5 — Mastery
Exercise 5.1. Ek colleague argue karta hai: "Agar main 32 cores wale SM se 128 cores wale SM par switch karun, toh mera 32 threads ka single warp faster chalega." Unki reasoning ko steel-man karo, phir precisely refute karo, aur batao kya cheez sach mein better hoti hai.
Recall Solution 5.1
Steel-man (sabse strong honest version): zyada ALUs zyaadatar zyada kaam per unit time karte hain, aur , toh speedup table par hona lagta hai.
Refutation: real hai lekin yeh throughput par apply hota hai, na ki ek single warp ki latency par. Ek warp instruction per issue atomic hoti hai — uska floor ek cycle hai chahe 32 ya 128 cores hon. 32-core SM par, ek warp/cycle cores ko fully occupy karta hai. 128-core SM par, ek warp phir bhi ek cycle mein khatam hota hai, lekin ab (multiple schedulers ke zariye) 4 warps tak ek cycle mein issue ho sakte hain. Toh 128-core SM har cycle mein zyada warps complete karta hai — lekin koi bhi ek warp exactly utna hi fast hai jitna pehle tha.
Verdict: aggregate warp throughput ~ scale karta hai; per-warp latency unchanged hai. Yeh fark hai ek race faster khatam karne (latency) aur char races side by side chalane (throughput) mein.
Exercise 5.2. Ek kernel 1000 GB/s peak DRAM bandwidth wale GPU par transaction efficiency achieve karta hai. (a) Tumhe actually kitni effective bandwidth milti hai? (b) Ek rewrite accesses ko fully coalesced banata hai (). Effective bandwidth kitne factor se improve hoti hai, aur kya compute per element change hota hai?
Recall Solution 5.2
(a) Effective bandwidth efficiency times peak hai: (b) par: Compute per element unchanged hai — coalescing sirf bytes kaise move hote hain fix karta hai, na ki har thread kitne arithmetic ops karta hai. Tumne memory ko better banaya; ALUs exactly same math karte hain. Isliye memory-bound kernels sirf ek pure access-pattern rewrite se speed mein leap le sakte hain, koi algorithm change nahin. (Seedha relevant hai 9.1.02-neural-network-training-on-GPUs se, jahan huge tensor reads dominate karte hain.)
Exercise 5.3. Prove karo ki "compute intensity badhana hamesha ek fixed latency hide karne ke liye required warps ghatata hai," aur woh ek degenerate case identify karo jahan formula break karta hai.
Recall Solution 5.3
Shuru karo: Yahaan (schedulers) aur (stall cycles) fixed positive numbers hain, aur . ki function ke roop mein, yeh hai, jo ke liye strictly decreasing hai: double karne se half ho jaata hai. Toh memory op ke beech zyada compute hamesha needed warps ghatata hai.
Degenerate case: . Agar ek warp stalls ke beech zero useful compute karta hai, toh undefined hai (division by zero) — physically, ek warp jo kabhi compute nahin karta woh kuch bhi hide karne mein help nahin kar sakta; tum chahe kitne bhi warps launch karo pure stalls se latency cover nahin ho sakti. Formula assume karta hai (memory ops ke beech kam se kam ek real instruction).