WHY can't we just write everything straight to DRAM (write-through, no caching)?
Because writes are extremely frequent; going to DRAM every time would make a multi-GHz core spend almost all its time stalling. We want private caches. So we need a rule set that makes private caches behave like one shared memory.
Two cores; initially X=0 lives only in DRAM. Both caches: I.
Core0 reads X. Miss → BusRd. No other cache has it → Core0 gets it E (clean, sole owner). Why E not S? Because the snoop response said "no sharers," so the sole-owner optimization applies.
Core0 writes X=1. Hit in E → silent upgrade to M. Why this step? In E we know we're alone, so no invalidation needed — zero bus traffic. Memory now stale (still 0), but that's fine; M owns the truth.
Core1 reads X. Miss → BusRd. Core0 snoops, sees it has M → flushes value 1 (cache-to-cache, also updates memory), drops to S. Core1 installs S with value 1. Why this step? The flush is mandatory; otherwise Core1 would read stale DRAM 0. SWMR transitions from "single writer" to "multiple reader."
Core1 writes X=2. Hit in S → issue BusUpgr/Invalidate → M. Core0 snoops the invalidate, its S copy → I. Why this step? To write, you must be the single writer; everyone else must be invalidated first.
Result: at every step exactly one writer or many readers — never both. Reads always return the latest value.
Imagine four kids each with a personal whiteboard copying the same number from a big chalkboard (DRAM). If one kid changes his number but the chalkboard and other kids don't know, they'll all argue. So they make rules with sticky notes:
M = "I changed it and I'm the ONLY one with the new number — the chalkboard is out of date, ask me!"
E = "I'm the only one who copied it and I haven't changed it yet."
S = "Several of us copied it, but nobody changed it — we all agree."
I = "My whiteboard is blank/wrong, ignore it."
Rule: before any kid changes his number, he yells "everyone erase yours!" so there's never a situation where one kid edits while others read old stuff. That yelling is the bus broadcast, and the whole game is MESI.
What invariant does cache coherence enforce per memory line?
Single-Writer / Multiple-Reader (SWMR): at any instant one writable copy OR many read-only copies, never both.
What do the letters M, E, S, I stand for?
Modified, Exclusive, Shared, Invalid.
Difference between M and E?
Both are sole copies; M is dirty (memory stale, write-back needed), E is clean (matches memory, no write-back, can silently upgrade to M).
Why does the E state exist (performance reason)?
It lets a write to a sole clean line upgrade silently to M with zero bus traffic, since the cache already knows no other sharers exist.
What bus message is sent on a write miss or write-to-Shared?
BusRdX / Read-For-Ownership (RFO) — read with intent to write, which invalidates other copies.
A cache in M state snoops a BusRd from another core. What happens?
It flushes the dirty data (cache-to-cache + update memory) and transitions M → S.
A cache in M state snoops a BusRdX. What happens?
It flushes the data and transitions M → I.
Coherence vs consistency — what's the difference?
Coherence = all cores agree on the value timeline of a single address. Consistency = the ordering of operations across different addresses; needs the memory model/fences.
What is false sharing?
Different cores writing different variables that share one cache line, causing the line to ping-pong (M-invalidate cycles) despite no real data sharing. Fix: pad/align to separate lines.
What is a coherence miss?
A miss caused because another core's write invalidated this core's copy (state went to I), not because of capacity/conflict.
On a read miss with no other sharers, which state is entered, and why?
E (Exclusive), because the snoop response indicates no other cache holds the line.
S-state write: which transition and message?
Issue BusUpgr/Invalidate, transition S → M, all other S copies go to I.
Dekho, multicore CPU mein har core ka apna private cache hota hai — speed ke liye, taaki baar-baar DRAM tak na jaana pade. Problem yeh hai ki cache sirf ek copy hai. Agar Core0 ne X=5 cache kiya, aur Core1 ne apne cache mein X=9 likh diya, toh Core0 abhi bhi purana 5 padhega. Yeh galat hai. Cache coherence ka kaam hai yeh guarantee dena ki har core ek hi address ke liye ek consistent value dekhe, jaise sirf ek hi copy ho. MESI isi contract ko hardware mein lagu karta hai.
MESI ka matlab hai char states har cache line par: Modified (maine change kiya, sirf mere paas latest hai, DRAM purana hai), Exclusive (sirf mere paas copy hai, abhi tak change nahi kiya, clean hai), Shared (kai cores ke paas read-only copy hai, sab agree karte hain), aur Invalid (mera data kachra hai, ignore karo). Golden rule yaad rakho: ek writer (M) ya bahut saare readers (S), dono ek saath kabhi nahi — isko SWMR (Single Writer Multiple Reader) bolte hain.
Sab cache ek bus par snoop karte hain, yaani doosre cores ki requests sunte rehte hain. Jab koi core likhna chahta hai, woh BusRdX (read-for-ownership) bhejta hai jo baaki sabki copies ko Invalid kar deta hai. E state ka magic yeh hai: agar tum already Exclusive ho aur write karte ho, toh bina koi bus traffic ke silently M ban jaate ho — kyunki tumhe pehle se pata hai koi aur sharer nahi hai. Yeh bandwidth bachata hai.
Do important warnings: pehla, coherence ≠ consistency. Coherence sirf ek address ki value sabko same dikhata hai; lekin alag-alag addresses ka order (X pehle ya Y pehle visible hua) coherence guarantee nahi karta — uske liye fences aur atomic chahiye. Dusra, false sharing se bacho: agar do cores alag-alag variables likhte hain jo same 64-byte line mein hain, toh line dono cores ke beech ping-pong karti hai aur program slow ho jaata hai — fix hai alignas(64) se variables alag line par daalna. Yeh chhoti baat parallel programs ka sabse bada hidden killer hai.