Yes. A fence orders a core's own accesses. It does not clean caches. Take SB from Litmus Tests: SB and MP and put a fence F between each core's store and load: C0 runs W(X)=1, F, r1=R(Y), and C1 runs W(Y)=1, F, r2=R(X). X and Y are in different lines, X = Y = 0 initially, no cached copies, MSI.
Model | SB (r1, r2) = (0, 0) | Why |
|---|---|---|
TSO, no fences | Allowed | Each load passes its own core's buffered store to the other address. |
TSO, fence between store and load | Forbidden | Each load waits until its own store is globally visible, so whichever load runs second reads 1. |
In protocol terms, the fence stalls C0's load of Y until the buffered W(X)=1 has drained. Draining needs the line in M: C0 sends GetM, H sends Inv to any sharers and collects their Inv-Acks, and Data with M permission arrives. Only then can the store be written into the line. The rows follow C0 and line X. C1's side is the same for Y.
Step | C0 state / value | C1 state / value | H directory | Memory | Newest data |
|---|---|---|---|---|---|
Start | I / - | I / - | U | 0 | memory: 0 |
L. Store X=1 enters C0's store buffer | I / -, X=1 buffered | I / - | U | 0 | memory: 0 |
L. Fence (local), C0's load of Y stalls | I / -, X=1 buffered | I / - | U | 0 | memory: 0 |
1. GetM at H | IM^D / -, X=1 buffered | I / - | U, pend GetM C0 | 0 | memory: 0 |
H reads memory | IM^D / -, X=1 buffered | I / - | U, pend GetM C0 | 0 | memory: 0, Data(0) in flight to C0 |
2. Data at C0 | M / 0, X=1 buffered | I / - | U, pend GetM C0 | 0 | C0 and memory: 0 |
(assumed) grant delivered | M / 0, X=1 buffered | I / - | exclusive(C0) | 0 | C0 and memory: 0 |
L. Buffered store drains into the M line | M / 1 | I / - | exclusive(C0) | 0 | C0: 1 |
L. Fence (local), ordering satisfied | M / 1 | I / - | exclusive(C0) | 0 | C0: 1 |
The two messages are the cold write of MSI Protocol. What is new is the stall: the load of Y may not be performed until the row where the store drains. After the fence memory is still 0. Nothing in the ordering rule needs a PutM, because C0's M copy is the coherent source of 1 and H forwards any later request to it.
The litmus block in Litmus Tests: SB and MP models the fence as an operation that may execute only when its own core's buffer is empty, and asserts that SB with fences loses (0,0) under TSO while plain SB keeps it.
Operation | Required effect in the stated example | Not automatically required |
|---|---|---|
TSO full fence | Older buffered stores globally ordered before younger memory operations proceed. | Write back every M line to memory. |
Clean to a named target | Transfer current dirty data to that target under the maintenance contract. | Invalidate every cached copy. |
Invalidate a clean copy | Remove local usable permission safely. | Establish all cross-location ordering. |
A fence that returned because some line's tag reads M, while a store is still buffered ahead of the cache, would let (0,0) back in. Conversely, forcing a writeback does not by itself prove the required instruction ordering.
For a real instruction, read the architecture's access classes and scope. FENCE rw,rw is RVWMO's full fence. SB needs only FENCE w,r. MP needs FENCE w,w on the writer and FENCE r,r on the reader. Device, instruction-fetch and persistence operations need their own contracts.
H records the exclusive holder and resolves a request with C0 rather than trusting stale memory. Coherent sourcing preserves the value independently of whether the fence cleaned the cache.