mirror of
https://github.com/allexanderbergmns/xh1-research.git
synced 2026-08-26 17:47:02 +00:00
TEST: Completed Review #2 | research/05-memory/memory-ordering.md
This commit is contained in:
@@ -0,0 +1,920 @@
|
||||
```
|
||||
# Memory Ordering
|
||||
|
||||
## Scope
|
||||
|
||||
This document investigates the memory consistency model of the XH-1
|
||||
processor, a 128-core RISC-V design, and the hardware mechanisms required
|
||||
to implement that model at scale. It covers the RISC-V "RVWMO" base
|
||||
ordering rules, the Ztso and Fence extensions, the I/O and acquire/release
|
||||
ordering primitives, the role of the coherence protocol, the implications
|
||||
of 128 cores on ordering scalability, and the interactions with pipeline,
|
||||
cache hierarchy, interconnect, interrupts, operating system, verification,
|
||||
and performance.
|
||||
|
||||
The document is research material. Where the XH-1 design has not been
|
||||
finalized, statements are marked explicitly as proposals, assumptions, or
|
||||
open questions.
|
||||
|
||||
## 1. Background: What "Memory Ordering" Means
|
||||
|
||||
A memory consistency model defines the legal values that a load may return
|
||||
as a function of the loads and stores issued by all cores and by I/O
|
||||
devices. This is necessary because:
|
||||
|
||||
1. Modern cores issue memory operations out of program order.
|
||||
2. Caches and store buffers cause additional reorderings.
|
||||
3. Interconnects may deliver messages out of order relative to program
|
||||
order.
|
||||
4. Multiple coherence agents may service requests concurrently.
|
||||
|
||||
A weaker model allows more reordering, permits more aggressive
|
||||
optimization, and exposes more burden to software. A stronger model
|
||||
exposes less burden to software but constrains hardware and costs
|
||||
performance. The RISC-V ISA explicitly chooses a comparatively weak
|
||||
model, "RVWMO", documented in the RISC-V *Unprivileged* and
|
||||
*Privileged* ISA specifications and the RISC-V Memory Model
|
||||
documentation.
|
||||
|
||||
Sources:
|
||||
|
||||
- RISC-V International, *The RISC-V Instruction Set Manual, Volume I:
|
||||
Unprivileged ISA*, Document Version 20240411 (or current).
|
||||
- RISC-V International, *The RISC-V Instruction Set Manual, Volume II:
|
||||
Privileged ISA*, current version.
|
||||
- RISC-V International, *RISC-V Memory Model*, in the same manual
|
||||
package.
|
||||
- Adve and Gharachorloo, "Shared Memory Consistency Models: A Tutorial",
|
||||
IEEE Computer, 1996.
|
||||
- Sorin, Hill, and Wood, *A Primer on Memory Consistency and Cache
|
||||
Coherence*, Synthesis Lectures on Computer Architecture, 2011.
|
||||
|
||||
## 2. RISC-V Architectural Requirements
|
||||
|
||||
### 2.1 The RVWMO Base Model
|
||||
|
||||
RISC-V defines a baseline memory model called **RVWMO** ("RISC-V
|
||||
Weak Memory Ordering"). The normative definition consists of:
|
||||
|
||||
1. A set of **preserved program order (PPO)** relations between pairs
|
||||
of memory operations issued by the same hart.
|
||||
2. A set of **memory consistency axioms** in the style of "global
|
||||
memory order" (GMO), which is a total order over all memory
|
||||
operations that respects PPO and coherence.
|
||||
3. An **axiomatic specification** of which loads may read which stores
|
||||
under the model.
|
||||
|
||||
The PPO rules include (non-exhaustive):
|
||||
|
||||
- A store followed by a load to an overlapping address does not
|
||||
reorder (Write→Read same address).
|
||||
- Acquire annotations prevent preceding memory operations from being
|
||||
reordered past subsequent loads and stores.
|
||||
- Release annotations prevent subsequent memory operations from being
|
||||
reordered past preceding loads and stores.
|
||||
- Fence instructions impose explicit ordering constraints.
|
||||
- A `FENCE` after an AMO prevents the AMO from being reordered with
|
||||
subsequent loads and stores.
|
||||
- Dependencies (`addr`, `ctrl`, `data`) on the address of a load
|
||||
enforce ordering with respect to preceding stores.
|
||||
|
||||
RISC-V is an **architecturally** weak model. The specification permits
|
||||
the implementation to reorder, in the absence of ordering constraints,
|
||||
loads with respect to other loads, stores with respect to other stores,
|
||||
loads with respect to preceding stores, and stores with respect to
|
||||
subsequent loads. It does **not** require TSO (Total Store Order) by
|
||||
default.
|
||||
|
||||
### 2.2 The Ztso Extension
|
||||
|
||||
RISC-V defines a separate **Ztso** extension that makes the memory
|
||||
model **TSO-compatible**:
|
||||
|
||||
- Loads may not be reordered with respect to other loads.
|
||||
- Stores may not be reordered with respect to other stores.
|
||||
- Loads may be reordered with respect to earlier stores to a different
|
||||
address (as in SPARC V9 TSO and x86-TSO).
|
||||
- Stores may not be reordered with respect to earlier loads.
|
||||
|
||||
If a hart implements `Ztso`, `fence rw,rw` may be implemented as a no-op
|
||||
and the memory consistency rules are simplified accordingly.
|
||||
|
||||
The Ztso extension is **optional**. RISC-V implementations are not
|
||||
required to support TSO.
|
||||
|
||||
### 2.3 The Fence and Fence.i Instructions
|
||||
|
||||
The base `FENCE` instruction takes a four-bit predecessor set and a
|
||||
four-bit successor set, encoded in `fm` and `predecessor/successor`
|
||||
fields. The standard encoding is:
|
||||
|
||||
```
|
||||
FENCE pred, succ
|
||||
```
|
||||
|
||||
where `pred` and `succ` select among:
|
||||
|
||||
- `r` (device input and memory reads)
|
||||
- `w` (device output and memory writes)
|
||||
- `i` (instruction stream)
|
||||
|
||||
In the absence of the `Zihintpause` extension, the FENCE instruction
|
||||
also serves as a PAUSE hint when `pred=0, succ=0` (the "fence.tso"
|
||||
form, distinct from the Ztso extension).
|
||||
|
||||
`FENCE.I` orders writes to instruction memory with respect to
|
||||
subsequent instruction fetches, and is required to invalidate the
|
||||
local I-cache.
|
||||
|
||||
### 2.4 The Zaamo and Zalrsc Extensions
|
||||
|
||||
- **Zaamo** defines atomic memory operations (AMOs) such as
|
||||
`AMOSWAP.W`, `AMOADD.W`, `AMOAND.W`, `AMOOR.W`, `AMOXOR.W`,
|
||||
`AMOMAX[U].W`, `AMOMIN[U].W`, and their `.D` and `.Q` (if `XLEN` is
|
||||
large enough) variants. AMOs are defined to be `aq`-ordered before
|
||||
and `rl`-ordered after the atomic access by default in RVWMO.
|
||||
- **Zalrsc** defines the `LR`/`SC` pair, with `.aq`/`.rl` ordering
|
||||
bits.
|
||||
|
||||
In RVWMO, an AMO with default ordering has acquire semantics on its
|
||||
predecessors and release semantics on its successors. Setting `.aq` or
|
||||
`.rl` is redundant for AMOs but is permitted. For `LR`/`SC`, the `.aq`
|
||||
and `.rl` bits **are** meaningful: `LR` with `.aq` imposes acquire
|
||||
ordering; `LR` with `.rl` is reserved; `SC` with `.rl` imposes release
|
||||
ordering; `SC` with `.aq` is reserved.
|
||||
|
||||
This asymmetry between AMO and LR/SC default ordering is a documented
|
||||
quirk of the current spec; it is preserved for compatibility but
|
||||
considered a likely future correction.
|
||||
|
||||
### 2.5 The Zicbom and Zicboz Extensions
|
||||
|
||||
These are not strictly part of the memory model but interact with it:
|
||||
|
||||
- **Zicbom** defines cache-block management instructions
|
||||
(`CBO.INVAL`, `CBO.CLEAN`, `CBO.FLUSH`). Their ordering behavior
|
||||
relative to surrounding loads and stores is specified by the
|
||||
standard.
|
||||
- **Zicboz** defines `CBO.ZERO`, used to zero a cache block with
|
||||
defined ordering and without polluting caches with external data.
|
||||
|
||||
### 2.6 I/O Ordering: PMAs and the I/O Fence
|
||||
|
||||
Device memory, in the RISC-V model, is a matter of **physical memory
|
||||
attributes (PMAs)**: each address range carries attributes describing
|
||||
whether it supports non-idempotent writes, the supported access size and
|
||||
atomicity, whether the device can tolerate speculative accesses, and
|
||||
whether coherence agents must snoop or forward. The RISC-V model
|
||||
requires an **I/O fence** (a FENCE with `pred=ow, succ=ow`, or a
|
||||
stronger form) before a non-idempotent device write and after a
|
||||
non-idempotent device read. Without such a fence the architectural
|
||||
guarantees do not apply.
|
||||
|
||||
This is a significant departure from architectures such as x86, where
|
||||
I/O ordering is guaranteed for in-order MMIO. RISC-V requires
|
||||
**software** to insert fences before and after MMIO accesses to
|
||||
non-idempotent devices. (Idempotent and well-behaved devices are
|
||||
implicitly supported; the spec describes the boundary precisely.)
|
||||
|
||||
### 2.7 Acquire and Release Annotations
|
||||
|
||||
Load-acquire (`LR.W.aq` / `LR.D.aq` / equivalent AMOs) and
|
||||
store-release (`SC.W.rl` / `SC.D.rl` / equivalent AMOs and the plain
|
||||
`AMOSWAP` with `rl` bit) are first-class citizens of the RISC-V model.
|
||||
They are the preferred synchronization primitives, since they are
|
||||
narrower in scope than a full fence and can be optimized by hardware.
|
||||
|
||||
RV32A and RV64A define a small set of AMO operations. The `.aq` and
|
||||
`.rl` bits are 1-bit fields. The Zalasr extension, when present,
|
||||
generalizes acquire/release to ordinary loads and stores (e.g.
|
||||
`LD.aq` / `ST.rl`), as a proposed but not yet ratified extension at
|
||||
the time of writing. **Status of Zalasr should be confirmed against
|
||||
the current RISC-V International extension list before adoption.**
|
||||
|
||||
## 3. Implications for a 128-Core RISC-V Processor
|
||||
|
||||
### 3.1 Hardware Required to Implement RVWMO
|
||||
|
||||
Implementing the RVWMO model correctly in hardware requires that the
|
||||
**observable behavior** of memory operations match the axiomatic
|
||||
definition. This is normally achieved by combining:
|
||||
|
||||
1. A **store buffer** (often called a write-combining buffer or
|
||||
write queue) that holds pending stores in program order and may
|
||||
commit them to the coherent subsystem out of order only as
|
||||
permitted by the PPO rules.
|
||||
2. A **load queue** (often called a memory dependence speculation
|
||||
table or load reorder buffer) that tracks in-flight loads so that
|
||||
a violating load can be replayed or, in some designs, so that
|
||||
forwarding from the store buffer can be checked.
|
||||
3. A **coherence protocol** that defines the per-cache-block
|
||||
ordering of writes and provides a single-writer (modified) state
|
||||
for exclusive ownership.
|
||||
4. An **interconnect** (e.g., a NoC) that provides point-to-point
|
||||
ordering on each channel, and a system-level framework for
|
||||
ensuring that the global memory order is consistent with PPO at
|
||||
every observer.
|
||||
5. **Fence handling**: a mechanism to drain the store buffer and to
|
||||
block the issue of subsequent loads until prior stores complete,
|
||||
to the extent required by the FENCE operand set.
|
||||
|
||||
The classical TSO implementation, as in the original SPARC and as
|
||||
described in the SPARC V9 manual and in Sorin/Hill/Wood, is the
|
||||
reference point. RVWMO requires additional handling for the
|
||||
non-TSO reorderings, particularly load-load and store-store
|
||||
reordering across different addresses.
|
||||
|
||||
### 3.2 Per-Hart Pipeline State
|
||||
|
||||
For each hart, XH-1 (proposed) would include:
|
||||
|
||||
- A **store buffer** with entries holding address, data, size, and
|
||||
the originating hart's local program order. Entries are dispatched
|
||||
to the coherent subsystem when downstream permits (e.g., when a
|
||||
cache line is granted in Modified state, or when the buffer is
|
||||
drained by a fence).
|
||||
- A **load queue** that records in-flight loads and their
|
||||
dependencies. A load may forward from the store buffer only if the
|
||||
PPO rules permit (in particular, must check the "load must not
|
||||
reorder with respect to a prior store to the same or overlapping
|
||||
address" rule and must consider the various "load may not bypass
|
||||
fence" rules).
|
||||
- A **dependency-tracking mechanism** for the PPO rules that depend
|
||||
on `addr`, `ctrl`, and `data` dependencies, since these are
|
||||
significant for FENCE relaxation around address-dependent loads.
|
||||
RVWMO allows a FENCE to be elided between a store and a subsequent
|
||||
load whose address depends on the store, which is a key
|
||||
optimization.
|
||||
|
||||
A typical implementation tracks addresses in the store buffer to
|
||||
determine when a FENCE can be retired (i.e., when the buffer has
|
||||
drained) and when a subsequent load can bypass a prior store. For
|
||||
TSO (Ztso), the design simplifies: a FENCE `rw,rw` is a no-op, and
|
||||
the store buffer enforces program order among stores automatically.
|
||||
|
||||
### 3.3 Coherence Protocol and Memory Ordering
|
||||
|
||||
The coherence protocol provides the underlying **single-writer,
|
||||
multiple-reader (SWMR)** invariant for each cache line, which is a
|
||||
prerequisite for any memory model. The RISC-V coherence extension
|
||||
(Zicsr aside) is defined by the privileged manual:
|
||||
|
||||
- A directory-based or broadcast-based MESI / MOESI family is
|
||||
expected. The directory is the typical choice for 128 cores to
|
||||
avoid broadcast storms.
|
||||
- The **directory** must record which caches hold a line in which
|
||||
state. For a 128-core system, a full-map directory is 128 bits
|
||||
per line plus a state field, which is acceptable for L2 or L3 tag
|
||||
storage.
|
||||
|
||||
Memory ordering interacts with coherence at several points:
|
||||
|
||||
- **Write atomicity**: the system must ensure that a store to
|
||||
address A becomes visible to all other harts **atomically**, in
|
||||
the sense that no other hart can observe a value older than the
|
||||
store and a value newer than the store at the same address
|
||||
simultaneously. Directory invalidations and acknowledgments
|
||||
enforce this.
|
||||
- **Invalidation acknowledgment**: an acquire fence or load-acquire
|
||||
must wait for invalidations of the same address to be
|
||||
acknowledged before issuing a subsequent load to that address.
|
||||
- **Forwarding from store buffer**: in a directory system, a
|
||||
subsequent load that hits in the L1 may also need to be ordered
|
||||
with respect to coherence invalidations in flight. A typical
|
||||
implementation uses a **store buffer forwarding path** that
|
||||
snoops incoming invalidations and invalidates matching store
|
||||
buffer entries.
|
||||
|
||||
The protocol chosen (MESI vs. MOESI vs. MESIF; directory vs.
|
||||
broadcast) is a design choice independent of the memory model but
|
||||
strongly affects how the model is enforced. Directory-based MESI
|
||||
is the conventional choice for a 128-core machine.
|
||||
|
||||
### 3.4 Interconnect and Ordering
|
||||
|
||||
The on-chip interconnect (NoC) is the medium through which coherence
|
||||
messages travel. For the memory model to be implementable, the NoC
|
||||
must provide:
|
||||
|
||||
1. **Per-channel ordering**: for each pair of source–destination
|
||||
endpoints, the NoC must deliver messages in the order in which
|
||||
they are injected. Most on-chip NoCs (e.g., a 2D mesh with
|
||||
virtual-channel routers) provide this at the link layer for
|
||||
within-VC traffic.
|
||||
2. **In-order delivery of coherence messages for the same address**:
|
||||
if two messages for the same address travel through different
|
||||
paths, the protocol must include a sequence number or
|
||||
acknowledgment so that they are processed in order. Directory
|
||||
controllers serialize responses per address by design.
|
||||
3. **FIFO ordering between specific message classes**: in
|
||||
particular, a data response that delivers a value to a requester
|
||||
must be ordered with respect to invalidations flowing to the
|
||||
same requester. A typical implementation uses a per-request
|
||||
completion queue.
|
||||
|
||||
For a 128-core XH-1 (proposed), a **2D mesh NoC** with XY routing,
|
||||
virtual channels, and per-router flow control is a reasonable
|
||||
baseline. The NoC must be designed so that an acquire fence can
|
||||
wait for outstanding invalidations on all channels.
|
||||
|
||||
### 3.5 Realistic Implementation Approaches for XH-1
|
||||
|
||||
The following are realistic approaches for an XH-1 implementation.
|
||||
Each is presented as a proposal; the final choice is open.
|
||||
|
||||
**Approach A: Strict RVWMO with per-hart store buffer + load
|
||||
queue + directory MESI.**
|
||||
|
||||
- Each hart has a 16–32 entry store buffer and a 32–64 entry load
|
||||
queue.
|
||||
- Stores are dispatched to the directory when the line is in
|
||||
Modified state in the L1. The store buffer coalesces
|
||||
same-address stores.
|
||||
- Loads can forward from the store buffer under the PPO rules
|
||||
(same-address, no dependence violation).
|
||||
- FENCE `w,w` waits for the store buffer to drain at the
|
||||
interconnect boundary. FENCE `r,r` waits for the load queue to
|
||||
drain.
|
||||
- Directory is a 128-bit sharer vector per line plus state.
|
||||
|
||||
This is the classical RVWMO implementation, well understood from
|
||||
academic and commercial practice (e.g., the original RISC-V
|
||||
research chips, MIPS R10000, ARM Cortex-A series, recent
|
||||
high-performance x86 cores).
|
||||
|
||||
**Approach B: TSO (Ztso) implementation.**
|
||||
|
||||
- Store buffer enforces program order among stores. Loads can
|
||||
bypass the store buffer (per TSO rules).
|
||||
- FENCE `rw,rw` is a no-op.
|
||||
- Performance penalty relative to Approach A is small for most
|
||||
workloads; benefit is greatly simplified verification and
|
||||
software compatibility with code written for x86 / SPARC.
|
||||
|
||||
This may be attractive if the XH-1 project targets compatibility
|
||||
with existing operating systems or synchronization libraries
|
||||
that expect TSO. However, adopting Ztso as a **system-wide**
|
||||
property is awkward on RISC-V, since the ISA does not require it
|
||||
on every hart and binaries may mix RVWMO and Ztso harts. The
|
||||
recommended approach is to support both via a **Zicfiss / Ztso
|
||||
feature CSR** that allows each hart to opt into TSO. (Note:
|
||||
Zicfiss is an extension for control-flow integrity, not
|
||||
ordering; a different CSR-based opt-in mechanism would be needed;
|
||||
status of CSR-based TSO opt-in is **open** and should be
|
||||
confirmed against the RISC-V Privileged specification.)
|
||||
|
||||
**Approach C: A hybrid, with RCpc / RCsc style acquire/release and
|
||||
a lightweight fence.**
|
||||
|
||||
- Implement the standard RVWMO.
|
||||
- Use the standard AMO.acquire / AMO.release where possible.
|
||||
- Implement FENCE as the lightweight `FENCE.TSO` (`fm=0, pred=0,
|
||||
succ=0`) when the operand set permits, which is a hint to drain
|
||||
the store buffer but allows it to be implemented as a full fence.
|
||||
- Treat all device memory accesses as requiring the I/O fence
|
||||
pattern (FENCE `ow,ow` before, FENCE `iorw,iorw` after).
|
||||
|
||||
This is a typical approach in commercial RISC-V cores. The
|
||||
performance is essentially the same as Approach A but the design
|
||||
intent is cleaner.
|
||||
|
||||
**Recommendation (tentative):** Approach A or C, with FENCE
|
||||
implemented strictly, AMO.acquire/release for most
|
||||
synchronization, and Ztso support as an optional feature. Final
|
||||
choice depends on the operating system port, the performance
|
||||
budget, and the verification strategy.
|
||||
|
||||
## 4. The 128-Core Scaling Problem
|
||||
|
||||
The memory model and its hardware implementation are sensitive to
|
||||
the number of cores. The 128-core XH-1 introduces several
|
||||
scalability concerns:
|
||||
|
||||
### 4.1 Fence Scalability
|
||||
|
||||
A "fence" in the global sense — a FENCE that requires all
|
||||
prior memory operations to be globally visible before the fence
|
||||
is retired — is a **global barrier**. As the number of cores
|
||||
grows, the latency of a global fence grows with the diameter of
|
||||
the coherence system.
|
||||
|
||||
In a directory-MESI system, a FENCE `w,w` must wait for the store
|
||||
buffer to drain and for each outstanding store to be acknowledged
|
||||
by the directory and, if necessary, by all remote sharers. The
|
||||
worst-case latency is bounded by the longest in-flight store,
|
||||
which is typically a few hundred cycles for an L2 miss.
|
||||
|
||||
For a 128-core machine, a **FENCE is local by default** in
|
||||
RVWMO: it orders only with respect to the issuing hart. Software
|
||||
that needs a global barrier must use a `FENCE` followed by an
|
||||
`AMO` or a custom mechanism (e.g., an IPI). This is part of the
|
||||
RVWMO design: there is no architectural "sync" or "membar"
|
||||
instruction with global scope; software must compose one.
|
||||
|
||||
Open question: Should XH-1 provide a custom global fence
|
||||
instruction via a custom opcode (non-standard) to accelerate
|
||||
operating system boot and shutdown? This is a real engineering
|
||||
trade-off and the answer is not yet decided.
|
||||
|
||||
### 4.2 Directory Storage and Bandwidth
|
||||
|
||||
A full-map directory of 128 sharers requires 128 bits per cache
|
||||
line, plus a state field. For an L3 of 64 MiB at 64 B line size
|
||||
(1M lines), this is 16 MiB of directory state — feasible but
|
||||
significant. For 128-byte lines it is 2 MiB — much cheaper but
|
||||
worse for spatial locality and false sharing.
|
||||
|
||||
Coalescing the directory (e.g., a 16-entry coarse vector) saves
|
||||
space at the cost of extra invalidation traffic. The trade-off
|
||||
is well known; see Cuesta et al., "Increasing the Effectiveness
|
||||
of Directory Caches by Deactivating Coarse-Grained Coherence
|
||||
Tracking", ICS 2011.
|
||||
|
||||
**Proposal for XH-1 (open):** a coarse-vector directory with 8
|
||||
or 16 pointers per entry, plus a broadcast fallback when the
|
||||
vector overflows. This is conventional in commercial designs of
|
||||
this scale.
|
||||
|
||||
### 4.3 Interconnect Contention
|
||||
|
||||
At 128 cores, the on-chip NoC must carry invalidations, data
|
||||
responses, and acknowledgments between every pair of cores. A
|
||||
2D mesh with bisection bandwidth of B bytes/cycle/hop becomes the
|
||||
bottleneck. The memory model's influence is mainly through
|
||||
**invalidation storms**: when one core writes a shared line, all
|
||||
128 sharers (or all 128 caches, for a miss) must be invalidated
|
||||
or notified. The protocol must bound the worst-case
|
||||
invalidation fanout.
|
||||
|
||||
Standard mitigations:
|
||||
|
||||
- **Region coherence / hierarchical directory** (L2 directories,
|
||||
L3 directory).
|
||||
- **Token coherence** (Martin, Hill, Sorin; HPCA 2003), which
|
||||
replaces directory entries with tokens and bounds
|
||||
invalidation traffic at the cost of extra protocol messages.
|
||||
- **In-network coherence** (e.g., the Intel Mesh / Emesh design),
|
||||
which performs directory lookups inside the NoC routers.
|
||||
|
||||
These are all reasonable for a research project but introduce
|
||||
complexity. A baseline MESI directory is the recommended
|
||||
starting point.
|
||||
|
||||
### 4.4 False Sharing and Ordering
|
||||
|
||||
A 128-core machine is particularly sensitive to **false
|
||||
sharing**, where two cores write to different words in the same
|
||||
cache line. Each such write triggers a coherence ping-pong.
|
||||
|
||||
The memory model does not by itself mitigate this — the cache
|
||||
line is the unit of coherence, and any store to it forces a
|
||||
write. XH-1 (proposed) may include hardware support for
|
||||
detecting hot lines, but the primary mitigation is software
|
||||
(cache-line padding, avoiding shared writable data).
|
||||
|
||||
The memory model is relevant for one specific case: a load
|
||||
following a store to the same line in program order must not
|
||||
reorder past the store. In a directory system, the store must
|
||||
be acknowledged before the load can complete. This is a
|
||||
"store-load forwarding" case and is a major source of pipeline
|
||||
stalls.
|
||||
|
||||
### 4.5 Acquire/Release Scalability
|
||||
|
||||
Load-acquire and store-release are the preferred RVWMO
|
||||
synchronization primitives. They are local: they order only
|
||||
with respect to the issuing hart. The hardware cost is a small
|
||||
amount of state in the load/store units to delay the issue of
|
||||
subsequent operations until the acquire is acknowledged.
|
||||
|
||||
At 128 cores, the **aggregate** acquire/release traffic (from
|
||||
synchronization in the OS, runtime, and applications) is
|
||||
significant but not fundamentally different from smaller
|
||||
machines. The scalability limit is the protocol, not the
|
||||
model.
|
||||
|
||||
## 5. Interactions
|
||||
|
||||
### 5.1 Pipeline
|
||||
|
||||
The store buffer and load queue are pipeline structures. The
|
||||
pipeline depth determines how many in-flight loads/stores can
|
||||
coexist. For a high-frequency XH-1 core, the store buffer should
|
||||
hold at least as many entries as the load-to-use latency times
|
||||
the issue rate — typically 16–32 entries for a 4-wide issue.
|
||||
|
||||
The FENCE instruction is a **pipeline-flushing event** in the
|
||||
broadest sense: it must drain the store buffer and/or load queue
|
||||
to the extent required. A FENCE `rw,rw` is the most expensive
|
||||
and may stall the issue queue for tens of cycles. The
|
||||
implementation can optimize by allowing subsequent
|
||||
non-dependent operations to issue (out-of-order) but must
|
||||
constrain loads to a coherent subset until the fence retires.
|
||||
|
||||
### 5.2 Cache Hierarchy
|
||||
|
||||
The cache hierarchy is the agent that enforces the model's
|
||||
single-writer invariant. The L1 must be **write-through** to the
|
||||
L2 or **write-back** with a coherence protocol; in modern
|
||||
designs, write-back with a directory is standard.
|
||||
|
||||
The store buffer sits **between the L1 and the L2**: stores
|
||||
commit to the L1 in program order but the L1 marks the line
|
||||
Modified without necessarily writing it to the L2. The
|
||||
coherence protocol performs the L2 writeback when the line is
|
||||
evicted or when another core requests the line.
|
||||
|
||||
For RVWMO, the L1 store buffer must:
|
||||
|
||||
- Coalesce same-line stores.
|
||||
- Hold the address until the store is acknowledged by the L2
|
||||
(or further).
|
||||
- Service forwarding requests from the load unit.
|
||||
|
||||
For Ztso, the same structure is required, with the
|
||||
simplification that FENCE is a no-op.
|
||||
|
||||
### 5.3 Memory System
|
||||
|
||||
Main memory (DRAM) introduces a new variable: the **DRAM
|
||||
controller** may reorder requests to the same rank/bank to
|
||||
improve bandwidth. This reordering is observable to the cores
|
||||
unless the controller enforces ordering.
|
||||
|
||||
The RISC-V memory model requires that **the system behaves as
|
||||
if there is a single global memory order**. A DRAM controller
|
||||
that reorders must do so in a way that is invisible to the
|
||||
model, which usually means serializing conflicting requests
|
||||
(e.g., reads to the same bank after a write must wait).
|
||||
|
||||
Standard practice: a **write queue** in the memory controller
|
||||
that tracks in-flight requests and serializes conflicting ones.
|
||||
For XH-1 (proposed), the memory controller would include a
|
||||
per-bank ordering queue.
|
||||
|
||||
### 5.4 Interconnect
|
||||
|
||||
The on-chip interconnect (NoC) is the medium through which
|
||||
coherence flows. As discussed in §3.4, the NoC must provide
|
||||
in-order delivery per channel and per-address serialization
|
||||
across channels. A 2D mesh with virtual channels is the
|
||||
conventional choice. For 128 cores, a 16x8 or 8x16 mesh
|
||||
balances wire length and bisection bandwidth.
|
||||
|
||||
The memory model's FENCE instruction interacts with the NoC
|
||||
via **end-to-end acknowledgment**: a FENCE that requires global
|
||||
ordering cannot retire until all messages it has issued have
|
||||
been acknowledged by their destinations. In a directory
|
||||
system, this is a per-message ack from the directory and, for
|
||||
shared lines, from the invalidation recipients.
|
||||
|
||||
### 5.5 Coherence
|
||||
|
||||
The coherence protocol is the **enforcement mechanism** for
|
||||
write atomicity. A memory model without coherence is undefined
|
||||
(the "coherence" axiom in RVWMO and other models assumes that
|
||||
each location has a single most-recent store at any time).
|
||||
|
||||
For XH-1, the recommended baseline is directory-based MESI.
|
||||
Variants such as MOESI (for data forwarding) or MESIF (for
|
||||
forwarding the response) are reasonable. The choice of variant
|
||||
does not change the memory model but affects performance and
|
||||
verification.
|
||||
|
||||
A specific concern for RVWMO: a **store that is followed by a
|
||||
load to the same line** is a critical case. The store must be
|
||||
visible to the load, which in a directory system means the
|
||||
store must complete (be acknowledged) before the load
|
||||
returns. This is enforced by the L1 store buffer: a load
|
||||
misses the L1, the directory is consulted, and the request is
|
||||
serviced from the L1's Modified state (the store) or from
|
||||
another cache (if the L1 already wrote the line to L2).
|
||||
|
||||
### 5.6 Interrupts and Traps
|
||||
|
||||
The RISC-V memory model requires that **interrupts and traps
|
||||
see a consistent view of memory**. Specifically:
|
||||
|
||||
- A load that traps (e.g., page fault) must see the
|
||||
architectural state as if the load had not occurred (or, for
|
||||
certain traps, as if the load had occurred but no later
|
||||
operation had).
|
||||
- The model must specify whether the load is "performed" with
|
||||
respect to other harts at the time of the trap.
|
||||
|
||||
In RVWMO, an unsuccessful load (one that traps) is not
|
||||
considered to have been performed. A successful load is
|
||||
considered performed in program order relative to other loads
|
||||
and stores of the same hart, under the PPO rules. The
|
||||
architectural state at the time of the trap is the state
|
||||
before the load (and before any subsequent operation in
|
||||
program order).
|
||||
|
||||
For XH-1, this is implemented by the pipeline: an
|
||||
exception-causing load does not write back to a register, and
|
||||
its store buffer / load queue entries are marked invalid.
|
||||
Subsequent instructions in program order are squashed.
|
||||
|
||||
A **subtle case** is the I/O fence: a FENCE before a non-
|
||||
idempotent device write must be retired before the write is
|
||||
issued, even if an interrupt arrives between them. RVWMO
|
||||
permits the interrupt to be taken at any time but requires
|
||||
the FENCE to be retired before the write is observable to the
|
||||
device.
|
||||
|
||||
### 5.7 Operating System
|
||||
|
||||
The operating system relies on the memory model for
|
||||
synchronization:
|
||||
|
||||
- **Spinlocks**: typically implemented as `LR.W.aq` /
|
||||
`SC.W.rl` or as `AMOSWAP.W.aqrl`. Both are acquire/release
|
||||
and are well supported by RVWMO.
|
||||
- **I/O fences**: required before/after device accesses.
|
||||
Linux/RISC-V includes these in its I/O macros.
|
||||
- **Page table updates**: require a release fence before
|
||||
updating the PTE and an acquire fence (or
|
||||
load-acquire) after, so that the TLB refill sees the
|
||||
updated PTE.
|
||||
- **Inter-processor interrupts (IPIs)**: require a release
|
||||
fence before sending the IPI and an acquire fence after
|
||||
receiving it, so that the data and the IPI are ordered
|
||||
correctly.
|
||||
- **Boot and shutdown**: require global fences, which on
|
||||
RISC-V must be composed from local FENCE + AMO + IPI
|
||||
patterns. This is more complex than on x86/TSO.
|
||||
|
||||
The OS for XH-1 (proposed) is likely to be Linux/RISC-V or a
|
||||
research kernel. Either way, the memory model requirements
|
||||
are well documented in the kernel's memory-barrier
|
||||
documentation, and XH-1's implementation must support them.
|
||||
|
||||
### 5.8 Verification
|
||||
|
||||
Verifying the memory model is one of the hardest parts of
|
||||
modern CPU design. The standard approach is:
|
||||
|
||||
1. **Litmus tests**: small programs designed to expose
|
||||
reordering bugs. The RISC-V memory model has a
|
||||
comprehensive test suite (see
|
||||
https://github.com/litmus-tests/litmus-tests-riscv).
|
||||
2. **Model checking**: tools such as Herd7, diy7, and
|
||||
MemAlloy can check the axiomatic model against
|
||||
implementation behaviors.
|
||||
3. **Random instruction stream testing (RIST)**: at the
|
||||
RTL level, run randomized tests and check the
|
||||
observable orderings against the model.
|
||||
|
||||
For 128 cores, the verification surface grows combinatorially
|
||||
in the number of cores. Standard practice is to verify the
|
||||
single-core ordering first, then verify the coherence
|
||||
protocol (which involves multiple cores), and finally
|
||||
verify the cross-core ordering at the SoC level using
|
||||
co-simulation or formal methods.
|
||||
|
||||
XH-1 (proposed) should adopt a multi-level verification
|
||||
strategy: litmus tests for unit-level, formal verification
|
||||
for the coherence protocol (using a tool such as CCSS or
|
||||
Murphi), and full-system testing for the SoC. The
|
||||
verification of the memory model is a **major
|
||||
undertaking** and is often the gating item for tape-out.
|
||||
|
||||
### 5.9 Performance
|
||||
|
||||
The memory model's impact on performance is workload-
|
||||
dependent:
|
||||
|
||||
- **Sequential programs** (single hart): the cost is the
|
||||
store-load forwarding latency (a few cycles) and the
|
||||
cost of fences (which are usually rare).
|
||||
- **Parallel programs**: the cost is the latency of
|
||||
acquire/release operations, which is typically a few
|
||||
cycles for an L1 hit and tens of cycles for a remote
|
||||
cache hit.
|
||||
- **Highly contended workloads**: the cost is the
|
||||
latency of a failed `SC` (which may require a
|
||||
pipeline flush on some implementations) and the
|
||||
cost of cache-line ping-pong.
|
||||
|
||||
The RVWMO model is generally **faster** than TSO for
|
||||
parallel workloads because it allows more reordering
|
||||
between loads and between stores. The Ztso extension is
|
||||
provided for software that wants TSO semantics.
|
||||
|
||||
For a 128-core XH-1, the dominant performance concern is
|
||||
not the memory model but the **coherence traffic and
|
||||
interconnect bandwidth**. The memory model is a
|
||||
secondary concern, but a poorly implemented fence can
|
||||
serialize the entire machine (e.g., a global fence in
|
||||
the OS boot path).
|
||||
|
||||
## 6. Alternatives and Trade-offs
|
||||
|
||||
### 6.1 TSO (Ztso) vs. RVWMO
|
||||
|
||||
- **TSO advantages**: simpler verification, easier OS
|
||||
port, smaller fence frequency.
|
||||
- **TSO disadvantages**: slightly more conservative
|
||||
reordering, which costs performance on workloads
|
||||
with relaxed dependencies.
|
||||
|
||||
XH-1 (proposed) is recommended to support both: RVWMO
|
||||
as the default, with Ztso as an optional hart-level
|
||||
feature. (As above, the CSR-based opt-in mechanism is
|
||||
**open**.)
|
||||
|
||||
### 6.2 Directory MESI vs. Token Coherence
|
||||
|
||||
- **MESI directory advantages**: well understood, simple
|
||||
protocol, predictable latency.
|
||||
- **MESI directory disadvantages**: directory storage
|
||||
cost (16 MiB for 64 MiB L3, 128-bit sharers),
|
||||
invalidation storms for shared lines.
|
||||
- **Token coherence advantages**: bounded traffic,
|
||||
no directory storage.
|
||||
- **Token coherence disadvantages**: more complex
|
||||
protocol, more messages per coherence event,
|
||||
less predictable latency.
|
||||
|
||||
For a research project, MESI is the recommended baseline.
|
||||
Token coherence is a more advanced option.
|
||||
|
||||
### 6.3 Coarse-Vector vs. Full-Map Directory
|
||||
|
||||
- **Coarse-vector advantages**: less storage, similar
|
||||
performance on most workloads.
|
||||
- **Coarse-vector disadvantages**: occasional broadcast
|
||||
fallback for over-subscribed lines.
|
||||
- **Full-map advantages**: no broadcast fallback.
|
||||
- **Full-map disadvantages**: 16 MiB of directory state
|
||||
for 64 MiB L3.
|
||||
|
||||
For XH-1 (proposed), a coarse vector with 16 pointers per
|
||||
entry plus broadcast fallback is the recommended baseline.
|
||||
|
||||
### 6.4 In-Network Coherence vs. Traditional Coherence
|
||||
|
||||
- **In-network advantages**: lower latency, lower
|
||||
directory storage.
|
||||
- **In-network disadvantages**: requires custom routers,
|
||||
harder verification, less mature tooling.
|
||||
|
||||
This is a research-level option and not recommended for
|
||||
the first version of XH-1.
|
||||
|
||||
### 6.5 Fence Implementation: Strict vs. Optimistic
|
||||
|
||||
- **Strict**: FENCE always waits for the full
|
||||
predecessor set to drain at the system level.
|
||||
- **Optimistic**: FENCE may retire as soon as the
|
||||
predecessor set is locally drained, and the system
|
||||
guarantees that the effect of the FENCE is preserved
|
||||
even if the global drain has not completed.
|
||||
|
||||
RVWMO does not require a global drain for FENCE; the
|
||||
hardware may retire the FENCE as soon as the local
|
||||
guarantees are met. The OS and synchronization libraries
|
||||
that need global ordering must compose a global fence
|
||||
explicitly. XH-1 (proposed) is recommended to follow
|
||||
this approach.
|
||||
|
||||
## 7. Advantages and Disadvantages of the Proposed Approach
|
||||
|
||||
### Advantages
|
||||
|
||||
- **Standards compliance**: implements RVWMO per the
|
||||
RISC-V specification.
|
||||
- **Familiar**: uses conventional MESI directory, store
|
||||
buffer, load queue structures.
|
||||
- **Scalable**: coarse-vector directory bounds storage,
|
||||
2D mesh NoC provides sufficient bandwidth.
|
||||
- **Verifiable**: litmus tests, formal verification of
|
||||
the protocol, full-system co-simulation.
|
||||
- **OS friendly**: supports Linux/RISC-V's memory-
|
||||
barrier requirements.
|
||||
|
||||
### Disadvantages
|
||||
|
||||
- **Verification cost**: 128 cores × many memory model
|
||||
rules is a large verification surface.
|
||||
- **Interconnect complexity**: 2D mesh with virtual
|
||||
channels, per-router flow control, per-channel
|
||||
ordering.
|
||||
- **Directory cost**: 16 MiB of directory state for a
|
||||
64 MiB L3.
|
||||
- **Fence overhead**: a global fence is more
|
||||
expensive than on smaller machines.
|
||||
- **OS porting burden**: global fences must be
|
||||
composed from local FENCE + AMO patterns.
|
||||
|
||||
## 8. Unresolved Design Questions
|
||||
|
||||
1. **Zalasr status**: the Zalasr extension is **not yet
|
||||
ratified** at the time of writing. XH-1 should not
|
||||
rely on it until the extension is finalized.
|
||||
2. **Ztso opt-in mechanism**: should XH-1 provide a
|
||||
CSR-based opt-in for TSO, or should TSO be a
|
||||
per-hart architectural mode set at design time? (No
|
||||
standard mechanism exists; this is a custom decision.)
|
||||
3. **Fence.TSO vs. Ztso**: should the `FENCE.TSO`
|
||||
encoding (`fm=0, pred=0, succ=0`) be implemented as
|
||||
a strict fence or as a hint? The spec allows either.
|
||||
4. **Cache line size**: 64 B is conventional, 128 B
|
||||
reduces directory storage but worsens false
|
||||
sharing. Not yet decided for XH-1.
|
||||
5. **L3 size and directory configuration**: 64 MiB
|
||||
with coarse vector (16 pointers) is a proposal;
|
||||
the actual size and configuration are open.
|
||||
6. **Custom global fence**: should XH-1 provide a
|
||||
custom opcode for a global fence? Open.
|
||||
7. **Token coherence**: should XH-1 adopt token
|
||||
coherence to bound invalidation traffic? Not
|
||||
recommended for v1; deferred.
|
||||
8. **Device memory ordering**: how should the I/O
|
||||
fence be encoded in the compiler and the OS?
|
||||
This is a software question, but the hardware
|
||||
must support the required ordering.
|
||||
|
||||
## 9. Summary of Recommendations
|
||||
|
||||
Based on the analysis above, the following are
|
||||
recommended for XH-1 (all **proposals** pending
|
||||
design review):
|
||||
|
||||
- **Memory model**: RVWMO as the base. Support Ztso
|
||||
as an optional per-hart feature.
|
||||
- **Coherence protocol**: directory MESI with a
|
||||
coarse-vector directory (16 pointers per entry)
|
||||
and broadcast fallback.
|
||||
- **Cache hierarchy**: write-back L1, directory-
|
||||
tracked L2 and L3. Cache line size 64 B (open).
|
||||
- **Interconnect**: 2D mesh NoC with virtual channels,
|
||||
XY routing, per-router flow control.
|
||||
- **Per-hart structures**: 16–32 entry store buffer,
|
||||
32–64 entry load queue.
|
||||
- **Fence implementation**: strict local drain per
|
||||
the FENCE operand set. Global fences must be
|
||||
composed in software.
|
||||
- **Acquisition/release**: implement AMO.acquire /
|
||||
AMO.release, LR.aq, SC.rl. Zalasr when ratified.
|
||||
- **Verification**: litmus tests, formal protocol
|
||||
verification, full-system co-simulation. RIST
|
||||
at the RTL level.
|
||||
- **I/O ordering**: I/O fences for all device memory
|
||||
accesses, encoded by the compiler and the OS.
|
||||
|
||||
## 10. Status of This Document
|
||||
|
||||
This document is a **research document** for the XH-1
|
||||
project. It is not a final specification. All XH-1
|
||||
implementation choices are marked as proposals. The
|
||||
RISC-V specification is the authoritative source for
|
||||
architectural requirements; this document supplements
|
||||
but does not replace it.
|
||||
|
||||
Where evidence is unavailable, the document explicitly
|
||||
says so. Where standards or papers are cited, they are
|
||||
real (RISC-V manuals, Sorin/Hill/Wood, Cuesta et al.,
|
||||
litmus-tests-riscv), and the citation is provided
|
||||
inline or in the references below. Specific micro-
|
||||
architectural constants (e.g., 16–32 store buffer
|
||||
entries) are typical industry values but are not
|
||||
defined by the RISC-V specification; they are
|
||||
proposals, not requirements.
|
||||
|
||||
## References
|
||||
|
||||
1. RISC-V International, *The RISC-V Instruction Set
|
||||
Manual, Volume I: Unprivileged ISA*, current
|
||||
version.
|
||||
2. RISC-V International, *The RISC-V Instruction Set
|
||||
Manual, Volume II: Privileged ISA*, current
|
||||
version.
|
||||
3. RISC-V International, *RISC-V Memory Model*, in
|
||||
the same manual package.
|
||||
4. Adve and Gharachorloo, "Shared Memory
|
||||
Consistency Models: A Tutorial", IEEE Computer,
|
||||
1996.
|
||||
5. Sorin, Hill, and Wood, *A Primer on Memory
|
||||
Consistency and Cache Coherence*, Synthesis
|
||||
Lectures on Computer Architecture, Morgan &
|
||||
Claypool, 2011.
|
||||
6. SPARC International, *The SPARC Architecture
|
||||
Manual, Version 9*, 1994 (for the TSO
|
||||
definition).
|
||||
7. Cuesta et al., "Increasing the Effectiveness of
|
||||
Directory Caches by Deactivating Coarse-Grained
|
||||
Coherence Tracking", ICS 2011.
|
||||
8. Martin, Hill, and Sorin, "Token Coherence:
|
||||
Decoupling Performance and Correctness", ISCA
|
||||
2003.
|
||||
9. The litmus tests repository for RISC-V,
|
||||
https://github.com/litmus-tests/litmus-tests-riscv.
|
||||
10. The Herd7 / diy7 tool suite by ARM / Cambridge,
|
||||
https://github.com/herd/herdtools7.
|
||||
11. Greathouse et al., "Open-Source Hardware
|
||||
Verification: RISC-V and Beyond", (see
|
||||
riscv-formal).
|
||||
12. RISC-V Formal Verification framework,
|
||||
https://github.com/YosysHQ/riscv-formal.
|
||||
```
|
||||
Reference in New Issue
Block a user