Skip to content

perf(rocr): shadow XGMI device batches, read timestamps with one load - #14338

Merged
saleelk merged 1 commit into
developfrom
users/saleelk/FixShadowSignal
Oct 28, 2026
Merged

saleelk merged 1 commit into
developfrom
users/saleelk/FixShadowSignal

Conversation

@saleelk

@saleelk saleelk commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

Two host-side costs remain for signals in device memory after #14115:

  1. XGMI-attached GPUs get no shadow. perf(rocr): resolve device-memory batch signals without reading the slot #14115 keeps a host-side copy of each batch member's
    Signal* so Signal::Convert resolves a device-memory batch handle without reading the slot's
    id and core_signal across the link. The copy was only made when
    GpuAgent::PcieStoresNeedFlush() is true, which is !xgmi_cpu_gpu_. On XGMI-attached systems,
    every signal API call on a device-memory batch member still read two fields across XGMI.
  2. Reading timestamps costs two round trips. SharedSignal::GetRawTs reads start_ts and
    end_ts with two 8-byte loads, so hsa_amd_profiling_get_dispatch_time and
    hsa_amd_profiling_get_async_copy_time cost two uncached reads per device-memory signal. CLR's
    built-in profiler (GPU_CLR_PROFILE_OUTPUT) attaches a signal to every dispatch, so this cost is
    paid once per kernel.

Technical Details

  • hsa_amd_signal_batch_create shadows every batch whose arena is in a discrete GPU's device pool
    (SignalBatch::Create takes the decision as shadow_members). The host reads a discrete GPU's
    memory across PCIe or XGMI either way. host_access_via_hdp is unchanged: it still decides HDP
    flushes after stores and emulated read-modify-writes, which only apply over PCIe.
  • An APU's device pools (properties().Integrated) are not shadowed: the host shares that memory,
    so reading the slot costs no link round trip. Before, an APU's batches were shadowed when its CPU
    link was not reported as XGMI.
  • SharedSignal::GetRawTs reads both timestamps with one 16-byte SSE2 load on x86-64. They fill one
    aligned 16-byte chunk of amd_signal_t. static_asserts pin the layout and the alignment the
    load relies on: alignof(amd_signal_t) >= 16 and amd_signal at a 16-byte offset in
    SharedSignal. Both signal allocators align to SharedSignal. Other architectures keep the two
    loads.

A host read of device memory on MI300X: 8-byte load 1.1 us, 16-byte load 1.1 us (one transaction),
32- or 64-byte load 2.2 us (two transactions).

Test Plan

  • rocrtst *Signal* and IPC tests.
  • Shadow stress (300 device batches, concurrent member loads while batches are recreated).
  • Per-call signal API cost on host and device batch signals.
  • hip_launch_latency -k -g with GPU_CLR_PROFILE_OUTPUT set, CLR device-memory queue signals on
    and off, against develop's ROCr; kernel durations from the traces compared.
  • A pageable-copy stress test under the profiler with HSA_ENABLE_SDMA=1 and 0, checking copy
    durations in the trace (hsa_amd_profiling_get_async_copy_time).

Test Result

MI300X (PCIe host):

  • rocrtst: 14/14 pass. Stress: pass (11k batch recreations, 15.7M concurrent member loads, 0
    mismatches).
  • Per call on a device-memory batch signal, median of 15 rounds of 5000 calls, develop and this
    branch interleaved: hsa_amd_profiling_get_dispatch_time 2.24-2.47 -> 1.15-1.27 us;
    hsa_signal_load_relaxed unchanged at 1.06-1.25 us. Host-memory signals: 6-7 ns both.
  • Profiled launches with device-memory signals: 100-node graph enqueue 463 -> 351 us, single
    launch + sync 11.7 -> 10.5 us. Host-memory signals unchanged.
  • Traces: no zero or negative kernel or copy durations; host-signal kernel median identical
    (3.328 us) on both ROCr builds; copy durations consistent with SDMA on and off.

Not run on an XGMI-attached system or an APU. On XGMI, device batches now take the shadow path
that #14115 measured over PCIe, where dropping the slot's id and core_signal reads took
hsa_signal_load_relaxed from 3.5 to 1.1 us; the XGMI saving is two reads across XGMI per call,
not measured here.

Submission Checklist

@therock-pr-bot

therock-pr-bot Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

✅ All Policy Checks Passed

Check Status Details
📝 PR Description ✅ Pass —
⛔ Forbidden Files ✅ Pass —
🧪 Unit Test ⚠️ Warning Error: Source/code files changed without an accompanying unit test.
Expected: add at least one test file named like test_<name>.py / test_<name>.cpp (or <name>_test.*).
Current: code file(s) changed: projects/rocr-runtime/runtime/hsa-runtime/core/inc/signal.h, projects/rocr-runtime/runtime/hsa-runtime/core/runtime/hsa_ext_amd.cpp, projects/rocr-runtime/runtime/hsa-runtime/core/runtime/signal.cpp; no test file found
🚫 Draft PR 🔜 To Be Enabled —
🚩 Feature Flag 🔜 To Be Enabled —
📊 Code Coverage 🔜 To Be Enabled —

🎉 All policy checks passed!

📖 Need help? See the Policy FAQ for details on every check and how to fix failures.

🙋 Wish to Override Policy?

@saleelk
saleelk marked this pull request as ready for review October 27, 2026 05:28
@saleelk
saleelk force-pushed the users/saleelk/FixShadowSignal branch from 2fdb2f4 to 161fea1 Compare October 27, 2026 06:17
@saleelk saleelk changed the title fix(rocr): shadow device-memory signal batches on XGMI-attached GPUs perf(rocr): shadow XGMI device batches, read timestamps with one load Oct 27, 2026

@cfreeamd cfreeamd left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI-assisted pre-review (for @cfreeamd)

The SSE timestamp load and the shadow-allocation refactor are structurally sound; amd_signal_t is aligned(64) and amd_signal is SharedSignal's first member, so the _mm_load_si128 address is 32-byte aligned at runtime.

@saleelk
saleelk force-pushed the users/saleelk/FixShadowSignal branch from 161fea1 to c98bac9 Compare October 27, 2026 22:21
Shadow device-memory signal batches on XGMI-attached GPUs.
hsa_amd_signal_batch_create keeps a host-side copy of each member's
Signal* for batches whose arena the host reaches across a link, so that
Signal::Convert resolves a handle without reading the slot's id and
core_signal from device memory. The copy was only made when the GPU's
stores need an HDP flush (PcieStoresNeedFlush), which is false when the
CPU is attached over XGMI. On those systems every signal API call on a
device-memory batch member still read two fields across XGMI before the
value. Shadow every batch in a discrete GPU's device pool instead. Host
reads of a discrete GPU's memory cross PCIe or XGMI either way; whether
stores need an HDP flush only decides how stores and read-modify-writes
are made, which is unchanged. An APU's device pools are not shadowed:
the host shares that memory, so reading the slot costs no link round
trip.

Read a signal's dispatch timestamps with one load. SharedSignal::GetRawTs
read start_ts and end_ts with two 8-byte loads, so for a signal in
device memory hsa_amd_profiling_get_dispatch_time and
_get_async_copy_time cost two uncached round trips. The two fields fill
one aligned 16-byte chunk of amd_signal_t, and one 16-byte load reads it
in a single round trip on x86-64. static_asserts pin the layout and the
16-byte alignment of amd_signal in SharedSignal that the load relies on.
On MI300X a host read of device memory costs 1.1 us for 8 or 16 bytes
and 2.2 us for 32 or 64.

MI300X: hsa_amd_profiling_get_dispatch_time on a device-memory signal
takes 1.15-1.27 us instead of 2.24-2.47 us. With the CLR built-in
profiler (a signal per dispatch) and device-memory queue signals, a
100-node graph launch enqueues in 351 us instead of 463 us, and a single
launch plus sync takes 10.5 us instead of 11.7 us. Host-memory signals
are unchanged.
@saleelk
saleelk force-pushed the users/saleelk/FixShadowSignal branch from c98bac9 to fc34b80 Compare October 27, 2026 23:13
@dayatsin-amd
dayatsin-amd self-requested a review October 28, 2026 02:29
@saleelk
saleelk merged commit 42dafc7 into develop Oct 28, 2026
399 of 403 checks passed
@saleelk
saleelk deleted the users/saleelk/FixShadowSignal branch October 28, 2026 16:52
@systems-assistant

Copy link
Copy Markdown
Contributor

TheRock Submodule Bump Activity

Newest first

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants