silicon atlasTHE HARDWARE REFERENCE
العربية
Reference/Memory & storage
Memory & storage

Atomics, barriers & memory ordering

Specify indivisible updates and the ordering needed to publish data safely.

“It worked on my CPU” is not a memory model.
Atomic access

Defined indivisible access.

LIVE EXPERIMENT

Follow an instruction

Runs on your device
12345678910
I1
F
D
E
M
W
I2
F
D
E
M
W
I3
F
D
E
M
W
I4
F
D
E
M
W
I5
F
D
E
M
W
I6
F
D
E
M
W
F · FetchD · DecodeE · ExecuteM · MemoryW · Writeback
Instructions6
Total cycles10
Visible cycle1

Overlap improves throughput. Dependencies introduce bubbles unless the implementation can forward or do independent work.

What this model includes

Five-stage, single-issue teaching model. Dependent mode inserts two idle issue cycles per instruction; real forwarding and hazards vary.

FOLLOW THE MECHANISM

What happens inside

1

Choose the guarantee

An atomic operation prevents a specified access from tearing and supports defined concurrency semantics. Relaxed atomics give atomicity without general publication ordering. Release/acquire can synchronize associated data when an acquire observes the relevant release under the language rules. Sequential consistency imposes a stronger ordering contract.

2

Respect all layers

Compiler reordering and hardware reordering are different concerns. A compiler barrier alone does not universally order hardware accesses. Device memory and DMA need platform-specific primitives. Lock-free does not mean wait-free, and a contended atomic can serialize a large number of threads.

PUT IT TO WORK

What this means for your code

Low-level engineer

Reason with the exact language model and target architecture. Use established primitives instead of inventing lock-free protocols from intuition.

Software developer

A mutex is often the clearest correct choice. Reduce shared mutable state before weakening memory order for speed.

A concrete exampleRead-only example
// C++ publication example; one producer and one consumer
std::atomic<bool> ready{false};
int payload = 0;
// producer
payload = 42;
ready.store(true, std::memory_order_release);
// consumer, after observing true
if (ready.load(std::memory_order_acquire)) use(payload);
GO TO THE SOURCE

Read the actual specifications

These references supply the underlying contracts and implementation details. The diagrams here are simplified teaching models.

Linux · Memory barriersLinux kernel documentation
RISC-V · ISA specificationsRISC-V International

Keep following the connection

Understood the idea? Keep a note of your progress.