Skip to content

RTU performance counters + perf-counter fixes - #435

Merged
tinebp merged 6 commits into
masterfrom
rtu-perf-counters
Oct 26, 2026
Merged

tinebp merged 6 commits into
masterfrom
rtu-perf-counters

Conversation

@tinebp

@tinebp tinebp commented Oct 26, 2026

Copy link
Copy Markdown
Collaborator

Adds ray-tracing unit performance counters (MPM class 15, --perf=15) to SimX and RTL, and fixes three existing perf-counter and doc problems found on the way.

Commits

  1. docs: fix the DXA MPM class and the perfetto converter path: the DXA doc said VX_DCR_MPM_CLASS_DXA = 6 (it is 16) and left out noslot_stalls; the Perfetto guide named a vortex_perfetto.py that doesn't exist (the script is ci/perfetto.py).
  2. perf: read TEX counters per socket, RASTER/OM per cluster: SimX read TEX at cluster scope, and vx_device_dump_perf summed TEX/RASTER/OM over every core. gfx_tex with 2 cores per socket reported 8192 reads for 4096; it now reports 4096.
  3. simx: keep MPM counters across kernel launches: nine SimX units cleared their counters on every launch; rtlsim doesn't, and neither does the SimX core. vecadd launched twice: dcache requests 224 → 448 (rtlsim 450).
  4. rtu: performance counters (MPM class 15): work counters (traces, rays, hits, misses, nodes, leaves, box/tri tests, instance descents, restarts, AHS/IS callbacks), activity counters (mem reads, busy, front-end busy, slot traversal/callback/starved time) and rtcache counters, socket scoped, CSRs 0xB03–0xB18. model_parity-rt_raycast checks the 12 work counters exactly; the raytracing runner checks the counter invariants. The SimX walker now models the bounded short stack with restarts (timing changes only on restart scenes; the rt_raycast perf baseline is unchanged).

Validation

  • tests/regression: 88/88 on SimX and rtlsim; instructions and cycles identical to master.
  • Raytracing suite: 37/37 SimX, 35/35 rtlsim, counter invariants hold.
  • model_parity-rt_raycast: 12 counters exact, cycles within 1.92%; fails as expected with the box-test strobe removed.
  • Verilator -Wall lint clean at XLEN 32 and 64 (default, A+Zacas, L1_LINE_SIZE=8, 2 clusters + L2/L3 + PERF, RTU+PERF incl. SOCKET_SIZE=2 and BVH6, TEX/RASTER/OM+PERF, TCU+DXA+PERF); SimX -DSIMX_FUNCTIONAL builds at XLEN 32 and 64.
  • fpga_gate rtu (Vivado 2024.2, U55C): PASS, Fmax 297.6 MHz (+0%), LUT +2%. All RTL changes are under PERF_ENABLE, which the DUT doesn't set. The LUTRAM/BRAM mix differs from the golden baseline, which predates Rv64 fixes #427/dispatch fix on single-packet inst #428/MUFU + Zfhmin #432 (they touch the RTU and RAM libraries); I didn't re-record it.

Known, not in this PR

  • rt_smoke_reform_sbt retires 91 instructions on SimX and 76 on rtlsim (also on master). SimX splits callback yields per SBT group; the RTL scheduler appears to yield all lanes in one batch. Needs a design decision.

🤖 Generated with Claude Code

tinebp and others added 6 commits October 25, 2026 20:34
- dxa_async_copy_multicast.md listed VX_DCR_MPM_CLASS_DXA = 6; it is 16
  in VX_types.toml. The perf CSR range is 0xB03-0xB08 (noslot_stalls was
  missing) and the VX_types.toml line reference is updated.
- perfetto_analysis.md and the ci/perfetto.py usage text called the
  converter vortex_perfetto.py; it ships as ci/perfetto.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The texture unit and its tcache are socket resources (VX_socket); the
rasterizer, OM unit and their caches are cluster resources (VX_cluster).
Every core of a socket/cluster reads the same MPM values.

- SimX read the TEX counters from the cluster, so with 2 sockets each
  core reported the sum of both sockets.
- vx_device_dump_perf summed the TEX, RASTER and OM counters over every
  core, so the totals were multiplied by SOCKET_SIZE (TEX) or by the
  cores per cluster (RASTER, OM). It now reads one core per socket or
  cluster, as the icache/dcache and L2/DXA printers already do.

gfx_tex, 2 cores, SOCKET_SIZE=2 (4096 texel reads): reported 8192, now
4096. Cycle counts unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The MPM counters are free-running from device reset: rtlsim only pulses
start between launches, and the SimX core already keeps its counters for
that reason. The caches, local memory, TEX, RASTER, OM, TCU (and its
tile buffer), DXA and the memory counters still cleared theirs in the
per-launch reset(), so a dump after several launches reported only the
last one.

vecadd launched twice, --perf=4: dcache reqs SimX 224 -> 448 (rtlsim 450),
memory reqs 20 -> 40. Instruction and cycle counts are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds the ray-tracing unit to the MPM counters, in SimX and RTL, read with
--perf=15. The set is limited to quantities every BVH ray-tracing unit
has, whatever its internal organization, so the counters stay meaningful
as the RTU evolves; the class's CSR window keeps room for more:

  rays       rays traced (active lanes of the trace instructions)
  hits       rays whose final result is a hit (misses = rays - hits)
  box_tests  ray/box intersection tests
  tri_tests  ray/triangle intersection tests
  callbacks  any-hit and intersection candidates returned to the shader
  busy       cycles with at least one ray in flight
  rtcache    reads and read misses (the RTU's memory demand)

CSRs 0xB03-0xB0A. The counters are socket scoped: the RTU and its rtcache
live in the socket, which sums its RTU cores.

- RTL: box/triangle test strobes from the scheduler, ray, hit and callback
  lane counts and busy in the core, summed in VX_socket and read through
  VX_csr_data. All of it is under PERF_ENABLE. The DBG_RTU_OCC debug block
  is removed.
- SimX: the same events (rays_issued, which counted traces, is renamed).
  The walker now models the hardware's bounded short stack with trail
  restarts instead of a flat restart charge, so box and triangle tests
  include the re-descents of restarted walks as in the RTL; this changes
  timing only on restart scenes (rt_smoke_deep_stack 8091 -> 9098 cycles).
  rt_raycast, the only raytracing perf baseline, is unchanged. The counters
  survive the per-launch reset, like the other MPM counters.
- Runtime: vx_device_dump_perf prints the class per socket and in total,
  with hit rate, tests per ray, memory requests per ray, utilization and
  rtcache hit rate; every raytracing test now dumps its counters.
- CI: model_parity cases can compare an MPM class's counters
  (parity_counters); model_parity-rt_raycast checks rays, hits, box_tests,
  tri_tests and callbacks exactly, and the counter invariants (hits <= rays,
  busy <= cycles).
- Docs: counter definitions in ray_tracing_architecture.md.

Validation: model_parity-rt_raycast passes (instructions equal, cycles
within 1.92%, the five work counters exact) and failed as expected with the
box-test strobe removed; callbacks match on rt_smoke_reform_sbt (4 on both
models); tests/regression 88/88 on SimX and rtlsim with instruction and
cycle counts equal to master; Verilator -Wall clean at XLEN 32 and 64.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When a kernel has .tbss but no .tdata, ld drops the empty .tdata and the
TLS image starts at the aligned .tbss, but __tdata_start stays at the
unaligned location counter. __tbss_offset then picks up 1-7 bytes of
padding and the per-hart stride __tls_block_size (e.g. 7, 11, 12) is no
longer a multiple of the word size, so every hart past the first gets a
misaligned tp and __init_tls zeroes .tbss at the wrong offset.

A kernel with one thread_local in .tbss and a 1-byte .rodata pad trapped
with "misaligned memory access" on rv32 and rv64; it now passes. Kernels
without TLS link to the same section layout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
LocalMemSwitch rebuilt each lane's request for the dcache and local-memory
paths without copying amo_cmp, so amocas always compared against 0: a CAS
with a nonzero expected value never matched, and CAS-increment loops
stalled at 1. RTL was correct. The amo regression cases only use an
expected value of 0, which is why they passed.

amocas(expected 9 -> 5) probe: SimX now matches rtlsim.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tinebp
tinebp force-pushed the rtu-perf-counters branch from 92ca343 to 97a9e19 Compare October 26, 2026 05:47
@tinebp
tinebp merged commit 50cb174 into master Oct 26, 2026
0 of 2 checks passed
@tinebp
tinebp deleted the rtu-perf-counters branch October 26, 2026 05:48
tinebp added a commit that referenced this pull request Oct 26, 2026
Brings in master's Rv64 fixes (#427), the single-packet dispatch fix
(#428), MUFU + Zfhmin (#432) and the RTU performance counters with
the perf-counter fixes (#435).

Conflicts keep the branch's structure where it reorganized the code:
- Cache bank and MSHR: the branch already carries #427's AMO write-back
  queue and commit-busy checks; its back-to-back fill path (no
  fill_inflight stall) and lazy-fetch queue stay.
- SFU: master's MUFU PE moves into VX_sfu_block, next to the RTU PE,
  and SimX's SFU dispatches MUFU ops per block through send_out.
- Host performance-counter reads: the branch's VX_csr_mpm already
  serves every counter master's VX_csr_data block reads.
- AFU/xrtsim memory ports, device caps (socket size), hardware
  profiles, changelog and command-processor docs: the branch's.
- SimX memory and local-memory perf counters now run from device
  reset, as master fixed them and as the RTL counts.
- The regression list gains mufu and zfhmin; the Xilinx DUT catalog
  gains mufu.

The perf baselines keep the branch's recorded values; they are
re-recorded on the merged tree by perf_gate --update-baselines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tinebp added a commit that referenced this pull request Oct 26, 2026
The master merge brought in the RTU perf counters (#435), but the RTU
class case in VX_csr_mpm was lost while resolving the branch's MPM
rework. With PERF_ENABLE and the RTU on, sysmem_perf.rtu/rtcache went
unread and lint failed (UNUSEDSIGNAL), which broke model_parity-rt_raycast.
SimX and the runtime already read this class.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant