One launch of the fly engine at 65,536 animals moves 55.9 GB through DRAM, between 59 and 87 percent of the card's 960 GB/s depending on which clock mode times it, and by the review's source-level estimate the biggest items are repeated reads of matrix factors and solve vectors, not of the Jacobian.
One launch of the fly engine at 65,536 animals reads 40.0 GB from memory and writes 15.9 GB. We timed the launch at 66.7 ms. That is 838 GB/s, 87 percent of the card's 960 GB/s, and it is not a measurement: the bytes were counted in one clock mode and the 66.7 ms was timed in another. Divide the same bytes by the 99.2 ms the profiler recorded while it counted and it is 563 GB/s, 59 percent; that time carries the slower clock mode and the profiler's own overhead.
So the honest headline is a range, and the explanation we wrote down for the bytes was wrong. This is the sequel to part 7, and the same outside review is the reason there is a correction.
The numbers, for the stage-7 bench (a standing, actuated fly, one thread per animal):
| Where the time comes from | Time per launch | Bytes over time | Share of 960 GB/s |
|---|---|---|---|
auto clock mode, counters from another mode |
66.7 ms | 838 GB/s | 87 percent |
profile_standard with counters collecting (includes profiler overhead) |
99.2 ms | 563 GB/s | 59 percent |
The counters only work in profile_standard (the next post, The profiler crashed because the CPU has a GPU, is the story of why). In that mode the kernel runs slower, and counting adds its own overhead on top, so neither time is the true one: 66.7 ms is too fast for these bytes, 99.2 ms too slow. The 87 percent pairs bytes from one mode with time from the other. We have not taken the same-mode measurement that would settle it.
Our first write-up said 52.6 GB and 790 GB/s, 82 percent, and called the step bandwidth bound. The review caught two errors in it: the write bytes did not follow the vendor's formula for combining two overlapping counters, and MiB were labeled MB. I recomputed from the saved counter files: 40.02 GB read, 15.87 GB written, 55.89 GB total. The conclusion that the step is heavy on memory survives the correction. The "82 percent" did not.
This is the stage-7 bench. It is a different benchmark from part 4's 104.4 ms figure, and I have not reconciled the two here.
The write-up said each animal reads 4.3 times its footprint because "the Newton loop re-reads J, D and H rows every iteration". It then ranked the fixes by that: put solver state in fast memory first, store the Jacobian more narrowly second.
The review counted accesses instead of allocations, from the source. Three results contradict the first explanation:
Its ranked read budget, per animal per step (source-level estimates):
| Work | Reads |
|---|---|
| Three factorizations | 143.3 KB |
| Triangular solves (about 7.9 full solves) | 110.7 KB |
| Kinematics, mass matrix, velocity forces and the rest of the setup | 85 to 100 KB |
| Noslip, excluding its final solve | about 72 KB |
Matrix-vector products (mulM) |
48.7 to 63.5 KB |
The review's total comes to 630 to 690 KB against 611 KB counted, so this is a budget, not an attribution of the hardware counters. It overshoots, and the review says so. The saved profile also reports zero scratch and zero LDS (the GPU's on-chip shared memory) for the kernel, so register spilling is not the story either.
Our own history said the same thing before the byte budget did. The probe in proto_factor.mojo factorized the fly's 74-dof mass matrix several ways. Microseconds per factorization:
| 1,024 animals | 65,536 animals | |
|---|---|---|
| One thread per animal, global memory (the engine) | 790 | 2,120 |
| One wave per animal, factor held in LDS | 79 | 4,130 |
A wave per animal is 10 times faster at 1,024 animals, where one thread per animal leaves the card idle. At 65,536 it is about 2 times slower: each row waits on two barriers, and packing several animals into a wave multiplies the LDS per wave until occupancy collapses. The whole step needs about 34 KB of LDS per animal, ten times the probe's share.
Then the byte-budget section ranked "per-animal solver state in LDS or registers" as lever one. That contradicts the probe above it in the same document, and the review pointed it out. Two other cuts bear on the title's other word:
Neither separates bytes from arithmetic cleanly, and we have not read an arithmetic counter. The "not math" half of the title is an inference from these two results, and the "memory" half rests on the byte count.
Count the accesses, not the allocation.
What counts:
What does not count:
The mistake cost us a ranking. We would have spent the next round narrowing Jacobian storage and building an LDS design that our own probe had already beaten at this batch size.
The planned fix is not measured. The review's first-ranked change keeps the solve vectors in registers and writes the result once. It estimates about 58 KB fewer reads and 28 KB fewer writes per step, worth 7 to 10 ms if bandwidth is the whole story. That is a prediction. Cache hits, instruction cost and occupancy can shrink it or turn it negative: the 74-dof solve wants a lot of registers, and the saved baseline already uses 112 vector registers per thread.
Run the byte counters and the kernel time in one clock mode on one launch of the 65,536-animal bench. If bytes over time is under 480 GB/s, half of the card's 960, the bandwidth-bound claim fails. We currently have 563 GB/s on the profiled side, which is above that line, but only by 17 percent. Then build the register-resident solve and see whether the 7 to 10 ms shows up. If it does not, the budget is wrong in a way the counters cannot show.
Provenance: one RX 7900 XTX (gfx1100), the standing-fly stage-7 bench at 65,536 animals; bytes under profile_standard with the integrated GPU unbound, time under auto; counters and review in the fly-connectome repo (docs/plans/BODY_ENGINE_OPT.md, .work/reviews/codex-engine-review.md, agent/body_engine/traffic.sh). The 563 and 838 GB/s figures are my recomputation from the saved counter files.
Komentarze
Brak komentarzy.
Zaloguj się aby skomentować.