6.1.11 · D5 · HinglishParallelism & Multicore

Question bankVector - SIMD instructions (SSE, AVX, NEON)

1,737 words8 min read↑ Read in English

6.1.11 · D5 · Hardware › Parallelism & Multicore › Vector - SIMD instructions (SSE, AVX, NEON)

Yeh page SIMD ke ideas par attack karta hai, arithmetic par nahi. Neeche har item ek one-line question hai jisme ::: se answer reveal hota hai. Answer cover karo, pehle apna guess commit karo, phir check karo. Agar koi galat ho, jo misconception usne target kiya wahi exactly woh hai jo real code mein tumhe bite karega.

Shuru karne se pehle, teen words jinpar hum poore time lean karenge — plain language mein earn kiye gaye taaki kuch bhi unexplained na lage:

Yeh teen pictures dhyan mein rakho; neeche har trap unhi mein se ek ka disguise hai. Parent note Data Paralelism, Loop Vectorization, aur Flynn's Taxonomy woh background hai jiske against tumhara test ho raha hai.


True or false — justify karo

SIMD speedup deta hai kyunki CPU vector instructions ke dauran faster run karta hai
False — clock speed bilkul same rahti hai; fayda yeh hai ki ek instruction ek saath lanes ko touch karti hai, isliye aap fewer instructions issue karte ho, tezi se nahi.
Ek 256-bit AVX register hamesha 8 elements process karta hai
False — 8 sirf 32-bit floats ke liye. Wahi 256 bits 4 doubles (64-bit each) ya 32 bytes (8-bit each) hold karta hai; element count = width ÷ element size.
Agar aapke array mein 1000 elements hain aur hai, toh SIMD exactly 125 vector instructions karta hai
True — exactly, isliye koi scalar remainder ki zaroorat nahi; danger tab aati hai jab , ka multiple nahi hota.
SIMD ek tarah ka MIMD hai Flynn's Taxonomy mein
False — yeh literally "SIMD" quadrant hai: ek instruction stream, bahut saare data streams. MIMD (multiple instruction, multiple data) alag cores hain jo apna apna program run karte hain.
Unaligned loads (_mm_loadu_ps) hamesha crash karte hain
False — yeh sahi se run karte hain, bas potentially slower kyunki data do cache lines mein split ho sakta hai. Yeh aligned load _mm_load_ps hai jo ek unaligned pointer par fault karta hai.
Ek dot product ka w-lane multiply aapko directly answer de deta hai
False — multiply partial products alag alag lanes mein produce karta hai; fir bhi aapko ek horizontal reduction (8→4→2→1) ki zaroorat hai lanes ke across sum karne ke liye ek scalar mein.
Register width ko 128 se 256 bits tak double karna hamesha real-world throughput double karta hai
False — theoretical width double hoti hai, lekin memory bandwidth, unaligned traps, aur scalar tails real gains ko 3×–6× ke paas cap karte hain; formula ek upper bound hai.
Saturating add aur normal add sirf tab differ karte hain jab values overflow hoti hain
True — 8-bit lanes ke liye, dono same result dete hain jab tak sum 255 se nahi badh jata; tabhi saturating 255 par clamp karta hai jabki normal ek chhoti number par wrap ho jata hai.
SIMD require karta hai ki saare lanes mein same value ho
False — lanes alag alag values hold karte hain (yahi "Multiple Data" hai). Unhe sirf wahi operation undergo karni padti hai (woh "Single Instruction" hai).

Error dhundho

float* p = malloc(16); _mm_load_ps(p); — kya unsafe hai?
malloc 16-byte alignment guarantee nahi karta, isliye aligned _mm_load_ps fault kar sakta hai; aligned_alloc(16, ...) ya unaligned _mm_loadu_ps use karo.
Ek loop for (i=0; i<n; i+=8) do_avx(a+i); jisme n=10 hai — kya break hota hai?
Yeh indices 0–7 process karta hai phir 8 par jump karta hai aur a[8..15] read karta hai, array se aage chala jata hai aur kuch skip nahi karta lekin garbage read karta hai; aapko last 2 elements ke liye ek scalar cleanup loop chahiye, ya n=10 koi 8 ka multiple nahi hai.
ADDPS ek array of doubles par use kiya — kya galat hai?
ADDPS packed single (32-bit floats) hai. 64-bit doubles par aapko ADDPD (packed double) use karna chahiye, warna aap har double ke bits ko do garbage floats ki tarah reinterpret karoge.
if (a[i]>0) b[i]++; else b[i]--; ko plain SIMD se vectorise karna — yeh kyun stall karta hai?
SIMD per-lane branch nahi kar sakta. Aapko saare lanes ke across dono increment aur decrement compute karne padenge aur phir comparison mask se blend karna hoga, double kaam karna — branchy code ke liye aksar scalar se bhi slow.
8 products ko ek vaddps se sum karna aur lane 0 read karna — kya missing hai?
vaddps do vectors ko lane-wise add karta hai, yeh ek single vector ke 8 lanes ko ek mein collapse nahi karta. Aapko phir bhi horizontal adds / extracts chahiye lanes ke across reduce karne ke liye pehle lane 0 total hold kare.
vmovaps [c], xmm0 jahan c ek buffer mein 17-byte offset hai — kya flaw hai?
17, 16 se divisible nahi hai, isliye yeh aligned store trap karta hai; ya toh buffer ko realign karo ya unaligned vmovups par switch karo.

Why questions

Vector instructions ki count mein ceiling kyun use hoti hai?
Ek partial final vector (maan lo 3 leftover elements) phir bhi ek poori vector instruction plus masking consume karta hai, isliye aap upar round karte ho — aap "0.375 of an instruction" issue nahi kar sakte.
Alignment kyun matter karta hai agar unaligned loads kaam karte hain?
CPU memory 64-byte cache lines mein fetch karta hai; ek aligned vector ek line ke andar hota hai (ek fetch), jabki unaligned ek do lines mein span kar sakta hai, us load ke liye memory traffic double kar deta hai.
Horizontal reduction inherently vertical multiply se kam efficient kyun hai?
Vertical ops data ko apni lane mein rakhte hain (fully parallel), lekin ek horizontal sum ko data lanes ke across shuffle karna padta hai, aur har cross-lane step pichle par depend karta hai, ek serial log-length chain banata hai jise wide ALU parallelise nahi kar sakta.
SIMD naturally Loop Vectorization aur Auto-vectorization ke saath pair kyun karta hai lekin recursion ke saath nahi?
Vectorization ko lanes mein pack karne ke liye ek fixed count of independent, uniform iterations chahiye; recursion mein data-dependent, variable-depth control flow hoti hai jisme aisi koi static, branch-free, parallel structure nahi hoti.
Memory bandwidth, lane count nahi, aksar true speedup ceiling kyun hoti hai?
Ek wide ALU 8 floats per cycle consume kar sakta hai, lekin agar memory subsystem sirf 2 floats per cycle deliver karta hai, toh extra lanes idle baithte hain — Cache Optimization dekhein kyun locality aur prefetching raw width se zyada matter karte hain.
Memory mein data ko contiguously pack karna SIMD ke liye kyun matter karta hai?
Ek single movaps consecutive addresses se elements grab karta hai; agar elements scattered hain, toh aapko unhe ek ek karke gather karna padega (ya costly gather instructions use karne padenge), one-load advantage destroy ho jata hai.
SIMD multicore parallelism ke same kyun nahi hai?
SIMD ek core ke andar ek instruction ko widen karta hai; multicore alag cores par alag instruction streams run karta hai. Yeh orthogonal hain — aap dono combine kar sakte hain (aur karte hain), saath mein har lane ki pipeline ke andar Instruction-Level Parallelism bhi.

Edge cases

Jab ho (single element) toh SIMD kitna speedup deta hai?
Essentially kuch nahi, aur possibly slowdown — aap ek poore vector ke liye load/store setup pay karte ho lekin sirf ek lane use hoti hai; chhote ke liye scalar code jeet jaata hai.
Jab exactly ho (e.g. 8 elements, ) toh ka kya hota hai?
Aapko ek perfect vector instruction milti hai, isliye — ideal case jahan ceiling koi waste nahi add karti.
Agar ho (ek element ek full vector se zyada), toh hidden cost kya hai?
elements ke liye do vector instructions issue hoti hain — doosri sirf ek useful lane process karti hai, isliye efficiency us leftover par lagbhag 50% tak gir jaati hai, exactly isliye remainder handling matter karti hai.
Ek saturating 8-bit add boundary par kya karta hai?
Yeh maximum 255 par clamp karta hai, 14 par wrap nahi karta; "extra" 15 discard ho jaata hai, jo brightness/colour ke liye sahi hai jahan values max se exceed nahi kar sakti.
Kya ek zero-length array () ko SIMD loop mein feed karna safe hai?
Sirf agar loop guard pehle n>0 check kare; vector instructions sahi hai, lekin ek naive for(i=0; i<n; i+=w) already body skip kar deta hai, jabki ek fixed unrolled call out of bounds read kar leta.
Jab saare lanes mein identical values hon, kya SIMD tab bhi help karta hai?
Haan throughput ke liye (phir bhi results ke liye ek instruction), lekin yeh information ki wastage hai — ek broadcast (vdupq_n/_mm_set1) jo ek scalar se lanes fill karta hai woh sahi tool hai, common jab ek constant jaise brightness har pixel mein add karte hain.
Recall One-line self-test

Woh ek sentence jo upar har trap unlock karta hai ::: SIMD same operation karta hai different data par, ek instruction wide — isliye jo bhi sameness (branches), width (element size), contiguity (alignment/gather), ya count (remainders) tod deta hai wahi jagah yeh fail hota hai.