Question bank — Atomic operations and CAS
6.1.9 · D5· Hardware › Parallelism & Multicore › Atomic operations and CAS
Yeh ek self-test page hai. Har line ek question ::: answer reveal hai. Answer ko cover karo, usse zor se argue karo, phir check karo. Goal facts memorise karna nahi hai balki un specific misconceptions ko khatam karna hai jo CAS invite karta hai. Har answer mein reasoning diya gaya hai, sirf haan/na nahi.
Shuru karne se pehle, ek vocabulary reminder taaki neeche koi aisa term use na ho jo tumne abhi earn nahi kiya:
Related deep material yahan hai: Lock-Free Data Structures, Spinlocks and Mutexes, Memory Barriers, ABA Problem Solutions, Cache Coherence Protocols aur Memory Consistency Models.
True or false — justify karo
CAS jo false return karta hai uska matlab memory corrupt ho gayi.
false ka sirf itna matlab hai ki address par value woh nahi thi jo tum expect kar rahe the — yeh bilkul normal, healthy signal hai ki doosra thread pehle pahunch gaya. Bas re-read karo aur retry karo.Ek single CAS instruction kabhi fail nahi ho sakta agar sirf ek thread chal raha ho.
expected hamesha CAS run hone par match karta hai. Failure ke liye concurrent writer chahiye (ya koi interrupt/signal handler jo same word ko touch kare).CAS atomic hai, isliye read + CAS se bana increment bhi atomic hai.
Agar CAS expected value dekhta hai, toh jabse maine padha tab se kuch nahi badla.
Lock-free algorithm guarantee karta hai ki har thread bounded time mein khatam hoga.
Test-And-Set aur CAS arbitrary synchronization banane ke liye equally powerful hain.
Load-Link/Store-Conditional (LL/SC) ABA problem ko free mein solve karta hai.
LOCK bus prefix aur cache-line locking same performance dete hain.
memory_order_relaxed ke saath successful CAS phir bhi aas-paas ke loads aur stores ko order karta hai.
relaxed swap ki atomicity guarantee karta hai lekin nearby memory operations par koi ordering impose nahi karta — Memory Barriers dekho. Doosre threads tumhari surrounding writes ko ajeeb order mein dekh sakte hain.Error dhundo
while (CAS(addr, old, new)); — is retry loop mein kya galat hai?
true return karta hai, toh yeh succeeding hote hue loop karta hai aur failure par rukta hai — intent ka ulta. Hona chahiye while (!CAS(...)).atomic_increment mein, ek coder old_val = *counter; ko loop ke bahar move karta hai "ek read bachane ke liye". Yeh bug kyun hai?
old_val stale ho jaata hai — yahi reason hai ki hum retry karte hain. Loop ke bahar ek baar padhne ka matlab hai ki har retry same galat expected use karti hai, toh CAS hamesha fail karta rehta hai (ya worse, spin livelocked ho jaata hai).Lock-free push: koi new_node->next = stack_top; ek baar loop se pehle likhta hai jo sirf CAS retry karta hai. Yeh galat kyun hai?
new_node->next ko har retry par current top ke saath re-link karna padta hai. Agar kisi doosre thread ne beech mein push kiya, toh next stale top ko point karta hai aur CAS-then-succeed ek broken chain install karta hai jo nodes drop kar deta hai.CAS(&top, A, B) ek pop mein succeed karta hai, toh hum A safely return karte hain. Author kya bhool gaya?
A free aur recycle ho chuka ho sakta hai (ABA). Pointer value A ka match karna yeh nahi kehta ki A->next abhi bhi valid hai, toh B garbage ho sakta hai. Version tag ya hazard pointer chahiye.Ek programmer ek busy 64-thread server par 32-bit version counter use karta hai "taaki yeh kabhi wrap na ho". Flaw kahan hai?
{ptr, version} pair dobara create karke aur ABA hole phir se khol ke. Kaafi wide counter use karo (aksar 64-bit pointer ke saath 64-bit, double-width CAS ke through).fetch_and_add CAS loop ke baad new_val return karta hai. Galti kya hai?
new_val return karna post-increment value return karta hai, un callers ko tod ke jo purani value par rely karte hain (jaise ek unique array index claim karna).Why questions
Hum new_val ko CAS ke bahar kyun compute karte hain ek locked region ke andar nahi?
CAS loop naturally contention ko bina kisi explicit lock ke kyun handle karta hai?
CAS ko "universal" atomic primitive kyun kehte hain?
CAS operations ko attached memory-ordering semantics ki zaroorat kyun hai?
acquire/release/seq_cst tags ke bina, doosra thread tumhara published pointer us data se pehle dekh sakta hai jise woh point karta hai, half-built state expose karte hue — Memory Consistency Models dekho.Heavy CAS contention actually ek mutex se slower kyun ho sakta hai?
LL/SC "interference detect karta hai aur retry karta hai" lock karne ke bajaye kyun?
Edge cases
Kya hota hai agar do threads literally ek hi instant par same location par CAS chalayein?
true return karta hai; doosra ab-changed value dekhta hai aur false return karta hai. Kabhi tie nahi hota — yahi atomic ka matlab hai.CAS kya karta hai jab expected value se equal ho lekin new bhi us se equal ho (value ko khud se swap karo)?
Kya ek empty stack par push (stack_top == NULL) ek special case hai jo CAS loop todta hai?
old_top simply NULL hai, new_node->next = NULL hai, aur CAS(&stack_top, NULL, new_node) pehla node normally install karta hai. NULL case same code se bina kisi branch ke handle ho jaata hai.Agar ek thread CAS retry loop ke andar poore ek second ke liye preempted ho jaaye, kya correctness kabhi violate hoti hai?
Kya delta = 0 ke saath Fetch-And-Add kabhi useful ho sakta hai?
Recall Jaane se pehle ek-line self-check
Agar CAS true return karta hai, kya yeh prove karta hai ki jabse maine padha tab se kuch nahi badla? ::: Nahi — yeh sirf prove karta hai ki value match ki; object ki identity ya history (ABA) verify nahi hoti.