Files
TheRock/rocm-systems/docs/superpowers/specs/2026-07-24-msc-atomic-alias-coherence-design.md
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

95 lines
4.1 KiB
Markdown

# MSC Atomic Alias Coherence Design
## Context
`L2Cache::atomic_rmw` acquires the device-wide atomic boundary before accessing
backing memory. The boundary flushes every registered L2 and then advances the
global coherence epoch while holding the L2 maintenance locks.
The direct-memory path therefore observes the flushed value. The linked-port
path instead reads through `MemorySideCache` (MSC). MSC is write-through and
keys clean cache lines by `(VMID, GPU virtual address)`. If two such keys alias
the same host storage, a clean line under one key can remain stale after another
key publishes dirty L2 data. An atomic RMW through the stale key can consequently
use the old value.
## Goals
- Make linked-port atomic RMWs observe the authoritative value after all L2
dirty data has been published.
- Ensure stale MSC aliases are not visible after a coherence epoch change.
- Preserve the existing device-wide atomic serialization and L2 locking model.
- Avoid scanning or invalidating the entire 128 MiB MSC on every atomic.
- Add regression coverage for two L2s sharing one MSC and HBM through aliased
VMID/virtual-address mappings.
- Remove the unused `register_cache` helper so there is one L2 registration
implementation and one ordering invariant.
## Design
Each MSC cache tag will record the device-coherence epoch at which its line was
filled or refreshed. MSC already protects tag lookup and replacement with the
corresponding stripe lock, so the epoch metadata will use that same protection.
On an MSC access:
1. Look up the `(VMID, GPU virtual address)` cache line under its stripe lock.
2. Compare the tag's recorded epoch with
`DeviceCacheCoherence::current_epoch()`.
3. If the epochs differ, require the old entry to be clean, invalidate it, and
refill the line from backing HBM.
4. Stamp a newly filled or refreshed entry with the current epoch.
5. Continue the requested read or write.
The atomic boundary's existing order remains unchanged:
1. Acquire the global exclusive coherence lock.
2. Lock every registered L2 maintenance mutex in sorted address order.
3. Flush dirty L2 data through MSC to HBM.
4. Advance the global coherence epoch.
5. Perform the linked-port RMW while the boundary remains held.
After step 4, any MSC alias retained from an earlier epoch is stale. The RMW
read therefore invalidates and refills that alias from HBM, where step 3
published the authoritative value. Other old aliases are invalidated lazily on
their next access.
MSC is write-through, so an epoch-stale entry is expected to be clean and can
be discarded without losing data. No MSC registration or new global lock is
needed.
## Alternatives
### Eagerly flush and invalidate the entire MSC
Registering MSC with the atomic boundary and calling `flush_all()` would be
simple, but it scans 1,048,576 tags and locks all 256 stripes for every atomic.
That cost is disproportionate to an individual RMW.
### Bypass MSC only for atomic backing accesses
Sending the RMW directly to HBM would obtain the correct operand, but clean MSC
aliases could remain stale and be returned after the atomic. A generation or
invalidation mechanism would still be required, while the backing protocol
would become more complex.
## Validation
Add a regression with two L2 caches linked to one MSC and HBM controller:
1. Map different `(VMID, GPU virtual address)` pairs to the same host word.
2. Read through the second alias to retain a clean MSC value of `0`.
3. Dirty `40` through the first L2 without immediately publishing it.
4. Increment through the second L2's atomic RMW.
5. Verify the callback observes `40`, the atomic result and host word are `41`,
and subsequent reads through both aliases return `41`.
Run the focused L2/MSC tests in Release and under TSan, followed by the relevant
non-benchmark test suite.
Measure end-to-end performance against commit `b685943638` using representative
large kernels from `rocjitsu-test-corpus`, including a large softmax, a large
pack/unpack case, and a large matrix multiplication. Use the same pinned-CPU,
alternating-run methodology as the previously published PR benchmark where the
harness permits it.