diff --git a/engine/README.md b/engine/README.md index e0454d6..adf16b1 100644 --- a/engine/README.md +++ b/engine/README.md @@ -1093,6 +1093,23 @@ on the Vulkan shaders unless `[Engine] Network = hip`: A model built with no options was compared shader by shader with the explicitly optioned build of each row, and the exact switches still reproduce the captures (`build/rr/f/nv/defaults.sh`). +### Byte-identical speed-ups (2026-10-19) + +RX 9070 XT, RADV 26.2.2, `d4r-m` 1280x720 -> 2560x1440 with `D4R_ENGINE_M_LAYER_STAMPS=1`. Every output frame, and +everything `D4R_M_DUMP` writes, is byte-identical to the previous build (M and L, HDR and LDR, the three +reconstruction tile tiers and the stress inputs). + +| change | stage | before -> after (us) | +|---|---|---| +| `layer_m.comp`: hardware FP8 saturation where a value cannot be infinite, and the V tiles in a buffer that is dead during the attention (more waves per SIMD) | frame | M 1583 -> 1566, L 2349 -> 2293 | +| `post_m.comp`: the second history candidate reuses the first one's sample when both have the same vector | reconstruction, uniform motion | 325 -> 288 | +| `post_m.comp`: both rows of a pixel pair take their Gaussian taps in one pass | reconstruction | 287 -> 265 (L 355 -> 320) | +| `down_m.comp`: the horizontal pass reads its texels into registers, no shared source tile | downsample | L 102 -> 91, M 117 -> 113 | +| `layer_m.comp`, `compile_m.py`: L's expansion stage at two windows per wave (`M_DEFS_DEC0L=-DWPW=1` for one) | expansion | 383 -> 366 | + +The network layers are separated by an execution-only barrier (`emptyStage`). A memory barrier there gives the same +output and costs about 60 us (M 1520 -> 1592), so it stays. + ## Preset L (runtime and shim path exist; experimental) Preset L (render preset 12, NVIDIA's model for Ultra Performance) is M's pipeline with its own input, expansion and diff --git a/engine/rr/README.md b/engine/rr/README.md index f7efb44..e0ac464 100644 --- a/engine/rr/README.md +++ b/engine/rr/README.md @@ -615,3 +615,17 @@ was measured and not built for D / E (`build/rr/f/nv/dstage.sh`, `dnl.sh`, level loads between a window's waves) decoder 0 takes the same time (803-818 us), encoder 1 the same, decoder 1 10% less. These windows also have 96 key tokens (3 KiB each for the tokens, the keys and the values at C = 32), which does not fit the 4 KiB a single wave can hold at full rate. + +### Byte-identical speed-ups (2026-10-19) + +RX 9070 XT, RADV 26.2.2, 1280x720 -> 2560x1440 with `D4R_ENGINE_RR_STAGE_STAMPS=1`. Every image of every frame is +byte-identical to the previous model on the replay and stress inputs, at levels 0 to 3. + +- `ptx2rr.py`: OCML's tanh (decoder 0's second kernel) in f32 where f64 was not needed. Exp's error term becomes + Dekker's exact product error; the polynomial below 0.625 stays in f64, because the driver folds away the f32 + rounding between its f64 steps. Identical to the previous function on all 2^32 inputs. dec0_1 475 -> 446 us, frame + 3.568 -> 3.537 ms. +- `exposure_f.comp` PASS 2: the exposure in one pass as NGX does it, each block adding its fixed-point sum to a 64-bit + total with an atomic add and the last block finishing. It needs `shaderBufferInt64Atomics`, which vkd3d-proton + enables; the shim reads the device's features through `GetDeviceFeatures`. Without it, or with a model that has no + `exposure_f2.spv`, the two passes run (`D4R_RR_TEST_NO_INT64_ATOMICS=1` forces them). Exposure 25.2 -> 14.9 us.