Timeline
Timeline
2025-10-26
init
This article introduces the weakly ordered memory model adopted by the ARMv8 architecture to improve performance, and discusses in detail the memory barrier mechanisms required to ensure memory access order in scenarios such as multi-core shared data. It deeply analyzes the working principles, core differences, and parameter configurations of Data Memory Barrier (DMB), Data Synchronization Barrier (DSB), and Instruction Synchronization Barrier (ISB).
Reference documents:
ARMv8.6 Chip Manual
- Chapter B2.3.7 Memory barriers
- Appendix K11 Barrier Litmus Tests
Reasons for memory barriers
The ARMv8 architecture adopts a weakly ordered memory model. Generally, this means that the order of memory accesses does not need to match the program order of load and store operations. The processor can reorder memory read operations relative to each other. Writes can also be reordered (e.g., write combining). Thus, hardware optimizations (such as the use of caches and write buffers) work in a way that improves processor performance, meaning that the required bandwidth can reduce latency between the processor and external memory, and hide the long latencies associated with such external memory accesses.
Reads and writes to normal memory can be reordered by hardware, subject only to data dependencies and explicit memory barrier instructions. Certain situations require stricter ordering rules.
- The processor uses superscalar technology: out-of-order issue, out-of-order execution, to improve instruction parallelism.

Either order of these two statements is possible because there is no dependency.
Memory consistency model
- Atomic consistency memory model
- Sequential consistency memory model
- Processor consistency memory model
- Weak consistency memory model
Compiler reordering
Weak consistency memory model
- In 1986, a paper by Dubois et al. described the definition of the weak consistency memory model
- The weak consistency memory model requires that synchronization accesses (accesses to global synchronization variables) are sequentially consistent, and before a synchronization access can be performed, all previous data accesses must be completed
- Before a normal data access can be performed, all previous synchronization accesses must be completed
- Processors use memory barrier instructions to implement the entire synchronization access functionality
- The basic principles of memory barrier instructions are as follows:
- All data accesses before the memory barrier instruction must be completed before the memory barrier instruction。
- All data accesses after the memory barrier instruction must wait for the memory barrier instruction to complete。
- Multiple memory barrier instructions are executed in order
- Processors subdivide memory barriers based on their scope
Example

Yes, because CPU0 might execute b=1 first

ARMv8 memory model
Innormal memoryimplementsweakly consistent memory model(weak ordering model)
Indevice memoryimplementsstrongly consistent memory model(strong ordering model)
The sequence of memory accesses may be inconsistent with the sequence in the code
ARMv8 architecture supports speculative accesses
- Prefetching data or instructions from memory
- Branch prediction
- Out of order data loads
- Speculative cache line fills
Predictive data accessOnly supportsnormal memory
The predictive prefetch of instructions can support any memory type
Under what circumstances do we need to consider memory barrier instructions?
- Sharing data between multiple different CPU cores (threads), such as mailboxes, etc.
- Sharing data with peripherals, such as DMA operations
- Modifying memory management strategies, such as context switching, page faults, and page table modifications
- Modifying the memory area for storing instructions (instruction memory): for example, self-modifying code, loading a program into RAM
Memory barrier instructions provided by ARMv8
- Data memoryBarrier (Data Memory Barrier, DMB) instruction
- Data synchronizationBarrier (Data Synchronization Barrier, DSB) instruction
- Instruction synchronizationBarrier (Instruction Synchronization Barrier, ISB) instruction
DMB instruction
Ordering of Load/Store instructions
- affects only data accesses (explicit data accesses, such as load and store)access sequence
- Data cache instructions are also considered data accesses
- ensures thatdata accesses before the DMBcan bedata access instructions after the DMBobserved
DMBpoints to note about the instruction
- the DMB instruction concernsthe sequence of memory accesses, and does not care when the data access instructions complete execution
- data access instructions before the DMB must be observed by data access instructions after the DMB

- The Data/unified cache instructions before DMB must complete execution before the memory access instructions after DMB (observed).

DSB instruction
Completion of Load/Store instructions
- The DSB instruction is much stricter than the DMB instruction.
- Afterany instruction after the DSB instruction, must wait until the following is completed,before it can start execution.:
- All data accesses before the DSB instructionall data accessesmust complete execution.
- Instructions such as cache, branch predictor, and TLB before the DSB instruction must complete execution.
Points to note about the DSB instruction
- DMB instructiononly concerns the ordering of data accesses., while the DSB instructionstarts to focus on when instructions must be completed
- Instructions after the DSB instruction must wait until:
- all data access instructions before the DSB have completed
- all Cache, TLB, and other instructions before the DSB have completed
the dsb instruction is more like a barrier

- In amulti-core system, cache and TLB instructions are broadcast to other cores, so the DSB instruction waits until these instructions are broadcast and replies are received before it is considered complete
difference between dmb and dsb, example:


the add instruction is not a data access instruction
Parameters of DMB and DSB instructions
Two dimensions of parameters can be specified, one isShareability domain, the other isbefore-afteraccess of
Shareability domain
- Full System
- Outer Shareable, prefix isOSH
- Inner Shareable, prefix isISH
- Non-shareable, prefix isNSH
before-after access (i.e., before and after memory barrier instructions, further refined as read/write memory barrier)
Read barrier: Load-Load/Store: suffix isLD
This means that the barrier requires all loads to complete before the barrier but
does not require stores to complete. Both loads and stores that appear after the
barrier in program order must wait for the barrier to complete.Write barrier: Store-Store: suffix isST
This means that the barrier only affects store accesses and that loads can still be
freely re-ordered around the barrier.Read-write barrier: Any-Any: suffix isSY
This means that both loads and stores must complete before the barrier. Both
loads and stores that appear after the barrier in program order must wait for the
barrier to complete.

DMB and DSB instruction case 1: mailbox
- Two CPUs share data via mailbox: shared memory and flags

DMB and DSB instruction case 2: DMA peripheral

The DSB instruction ensures that the DMA engine sees the latest data already in the DMA buffer before starting.
Execution order of cache maintenance instructions
- Cache maintenance instructions such as dc and ic have the same execution order as other memory access instructions, with no special characteristics.
- The instruction interface, data interface, MMU walker, etc., can be regarded as different observers.

Solution:

One-way barriers
Load-Acquire (LDAR)
All loads and stores that are after an LDAR in program order, and that match the shareability domain of the target address, must be observed after the LDAR.
Store-Release (STLR)
All loads and stores preceding an STLR that match the shareability domain of the target address, must be observed before the STLR.
There are also exclusive versions of the above, LDAXR and STLXR, available.
DMB and DSB are both bidirectional memory barrier instructions; armv8 supports “one-way” memory barrier primitives.
Acquire primitive: refers toRead and write operations after this barrier primitive cannot be reordered before it., usually this barrier primitiveis combined with load instructions
Release primitive: refers toRead and write operations before this barrier primitive cannot be reordered to after it, typically this barrier primitiveis combined with store instructions
Load-Acquire barrier primitive: Ordinary read and write operations can pass backward over this barrier instruction, but subsequent read and write operations cannot pass forward over it
in ARMv8ldarinstruction

- Store-Release barrier primitive: Ordinary reads and writes can pass forward over the Store-Release barrier instruction, but previous read and write operations cannot pass backward over it
- in ARMv8stlrinstruction

- Load-Acquire(Load-Acquire) andstore-release(Store-Release) are typically used in pairs
- ldarandstlrused in pairs:
- used to protect critical section data
- instructions within the critical section can be reordered (only within the critical section)
- has better performance than the full-featured DMB instruction
- has no effect on data cache maintenance instructions because it does not wait for cache broadcasts

instruction-level memory barrier instruction: ISB instruction
Context synchronization
the ISB instruction is powerful; it willflush the pipeline, and thenre-fetch instructions from the instruction cache or memory。
ISB instruction guarantees
- All instructions after ISB are re-fetched from the instruction cache or memory
- All context-changing operations before the ISB instruction have completed (context here refers to system register states, etc.)
Context-changing operations include:
- Operations on cache, TLB, and branch predictor, etc.
- Changing system registers, such as TTBR0
The ARMv8 architecture defines context as the state of the system registers and context-changing operations as things like cache, TLB, and branch predictor maintenance operations, or changes to system control registers, for example, SCTLR_EL1, TCR_EL1, and TTBRn_EL1. The effect of such a context-changing operation is only guaranteed to be seen after a context synchronization event.
The effect of context-changing operations is only visible aftera context synchronization eventCan see it later
Context synchronization events (context synchronization event)
- Taking an exception
- Returning from an exception
- ISB instruction
In practice, modifying system registers generally requires an ISB instruction, especially when modifying system control registers, but system registers like PSTATE do not require it
ISB instruction example 1: Enabling the FPU

An ISB instruction is required when changing the system control register
ISB instruction example 2: Changing page table entries

ISB instruction example 3: Self-modifying code

- No memory barrier instruction is used between updating the new code content (str x11, [x1]) and the clean data cache instruction
- Updating the code content and cleaning the data cache both operate on the same address and are data-related operations. There is a data dependency between them, which can be understood as the same observer
- Program order can be guaranteed between them
- A memory barrier is required between cleaning the data cache and invalidating the instruction cache
- Although these two cache instructions both operate on the same address, they are different observers (one is the data side, the other is the instruction side)
- The DSB here ensures that the instruction cache is invalidated only after the data cache is cleaned
- In a multi-core coherent system, the DSB instruction ensures that cache maintenance instructions complete execution, meaning other CPUs can observe the completion of cache maintenance instructions
- The ISB instruction is not broadcast, so CPU1 also needs to execute the ISB instruction
Non-temporal load and store pair
LDNP and STNP
LDNP and STNP are instructions that read or write a pair of register values. They also hint to the memory system that caching is not useful for this data. This hint does not prohibit memory system activities such as address caching, prefetching, or gathering, but merely indicates that caching is unlikely to improve performance. A typical use case might be streaming data, but it should be noted that effective use of these instructions requires a microarchitecture-specific approach.
Non-temporal loads and stores relax memory ordering requirements. In the above case, the LDNP instruction may be observed before the preceding LDR instruction, which could lead to reading from an unpredictable address in X0. For example:
1 | LDR X0, [X3] |
To correct the above issue, you need an explicit load barrier:
1 | LDR X0, [X3] |
Summary: Memory barrier instructions and cache/TLB maintenance instructions
- Data cache or unified cache maintenance instructions
- The DMB instruction can be used to ensure that cache maintenance instructions complete execution in the specified shareable domain
- Load-acquire and store-release barriers have no effect on data cache maintenance instructions (because they do not wait for cache broadcasts)
- Instruction cache maintenance instructions
- From the perspective of memory observers, the instruction cache and data cache are two different observers
- Execute a DSB instruction after the instruction cache maintenance operation completes, ensuring that all CPU cores in the inner shareable domain can see the completion of this instruction cache operation
- TLB maintenance instructions
- The unit that traverses page tables and the hardware unit for data access are actually two different observers of the memory system
- A DSB instruction needs to be executed after the TLB maintenance instruction to ensure that all CPUs in the inner shareable domain complete
- The ISB instruction does not broadcast, and if necessary, each CPU core needs to individually invoke the ISB instruction
Reading chip manual: memory barrier
ARM Architecture Reference Manual Armv8, for Armv8-A architecture profile
- B2.3.7 Memory barriers
- (Key points) Appendix K11 Barrier Litmus Test
ARM Cortex-A Series Programmer’s Guide for ARMv8-A
- 13.2 Barriers
Revisiting cache coherence and memory barriers
Introduction to the problem

The following execution order

CPU1’s assertion may still fail!!!
CPU stall caused by cache coherence protocol
- The MESI protocol is a bus-snooping and transmission-based protocol, whose bus transmission bandwidth is related to the load between CPUs and the number of CPU cores
- Changes in cache line state heavily depend on acknowledgment signals from other cache lines, meaning that state transitions can only proceed after receiving acknowledgments from all other CPUs’ cache lines. In a scenario with a busy bus or tight bus bandwidth, a CPU may need a long time to wait for acknowledgment signals from other CPUs, which significantly impacts system performance. This phenomenon is called CPU stall (CPU stall)
Example analysis: CPU stall caused by MESI protocol

In a 4-core CPU system, data A is shared on CPU1, CPU2, and CPU3, with their corresponding cache lines in state S (shared), and A’s initial value is 0. Data A is not cached in CPU0’s cache, so its state is I (invalid)
At this point, CPU0 writes a new value to data A (e.g., writes 1). How will the states of these cache lines change?
Time T1
CPU0 sends a local write operation signal to the bus

Time T2
CPU1, CPU2, and CPU3 all receive the BusRdX signal from the bus

Time T3
CPU1 checks whether its local cache has a copy of cached data A. CPU1 replies with aFlushoptsignal and sends the data to the bus, then sets its cache line state to invalid, changing the state to I, and finally broadcasts an acknowledgment signal.

Time T4

CPU2 and CPU3 both check their local cache, and the state changes from S to I
Time T5

CPU0 receives acknowledgment signals from all other CPUs, and only after confirming that no other CPU has a cached copy of this data or that the cached copy has been invalidated, can it modify data A. Finally, CPU0’s cache line state changes to M.
Summary
CPU0 has a waiting process; it needs to wait for acknowledgment signals from all other CPUs.

Optimization Method 1: Store Buffer

- No need to wait for acknowledgment signals from other CPUs, it canfirst write the data into the store buffer and continue executing the next instruction
- After CPU0 receives acknowledgment signals replied by all other CPUs, CPU0 then writes the latest value of data A from the store buffer into the local cache line and changes the cache line state to M.
Side Effects of the Store Buffer


Data a has a cached copy in CPU1’s cache, and its state is E.
Data b has a cached copy in CPU0’s cache, and its state is E.
Then, in a system with a buffer, will an assert failure occur?
Time T1CPU0 executes the statement “a=1”

Time T2CPU0 executes the statement “b=1”

Time T3CPU1 executes the statement “while(b==0)”

Time T4CPU0 receives the bus read signal.
Time T5CPU1 obtains the latest value of b

Time T6assert failed

flowchart of the entire process

solution for side effects: use write memory barrier instruction
- store buffer, which optimizes the performance degradation caused by long waiting for acknowledgment signals between multi-core processors. However, it stillcannot detect whether there is data dependency between multi-core CPUs
- write memory barrier statement(e.g., smp_wmb()), marks all data in the current store buffer, and thenflushes the store buffer, ensuring that data previously written to the store buffer is updated to the cache line before subsequent write operations can be executed

solution: add write memory barrier statement:

at time T1CPU0 executes the statement “a=1”

Time T2CPU0 executes “smp_wmb()”

Time T3: CPU0 executes the statement “b=1”

Time T4CPU1 executes the statement “while(b==0)”

Time T5

CPU’s data b state changes from E to S
Time T6

Time T7

Time T8
CPU0 receives the response signal for data a. It writes data a from the store buffer into the cache.

Time T9
Data item b in the store buffer is also written into the cache.

Time T10

Time T11

Time T12

Because the smp_wmb() instruction is added between a=1 and b=1, the operation of writing b=1 into the cache must be executed after writing a=1 into the cache.
Optimization Method 2: Invalidate Queue
- The store buffer in Optimization Method 1 is small and easily fills up
- One reason for CPU stalling is:Waiting for other CPUs to perform invalidate operations, which is time-consuming
- Invalidate Queue:Cache the invalidate operations, first send an acknowledgment signal to the requester, then slowly perform the invalidate operations, so other CPUs do not have to wait for a long time
The CPU responding to the invalidate operation does not need this data itself
- When a CPU receives a bus request and needs to invalidate a local cache line, it adds the request to the invalidate queue, then immediately sends an acknowledgment signal to the other party, without waiting for the cache line to be invalidated before responding
- If a CPU adds a request to the invalidate queue, before the corresponding invalidate operation is completed, the CPU cannot send any bus messages related to that cache line to the bus.

Side Effects of the Invalidate Queue

Assume the initial values of data a and data b are 0, data a has copies in both CPU0 and CPU1 with state S, data b has a cached copy in CPU0 with state E, will the assert succeed?


Solution to side effects: Use read memory barrier instruction
Read memory barrier instruction: The read memory barrier instruction canEnsure all invalidation operations in the invalidation queue are completed before executing subsequent read operations after the read barrier instruction。

Summary of memory barriers and cache coherence
In SMP, a simple load and store instruction is not simple; its behavior needs to be analyzed in conjunction with the MESI cache coherence protocol
Memory barriers need to be analyzed in conjunction with MESI cache coherence
Store buffers and invalidation queues are hardware optimization techniques, but they also bring some side effects
The read memory barrier instruction acts on the invalidation queue, ensuring that pending invalidation operations in the queue are completed as soon as possible before executing subsequent read operations
The write memory barrier instruction acts on the store buffer, ensuring that data in the store buffer is written to the cache before executing subsequent write operations
Memory barrier API provided in the Linux kernel
The Linux kernel abstracts a minimal commonality, within which each processor architecture can be supported

In-depth Understanding of ARM64 Memory Barrier Instructions

