Files
onion-mc/phase0/P2-linux-6700k-1080ti.md
T
logan 611a1a5952 docs: client-perf analysis, bench harness and work journal
Everything the next agent needs to run the Phase 2 optimisation loop on a
machine that can launch the client:

- analysis/client-perf/: LEVERS (ranked levers + corrections), BENCH-MATRIX
  (world, scenes, config IDs, blocks B0-B14 with decision rules),
  PLAYER-TUNING, SPAWN-TUNING, research briefs, the jar scanner and its
  output, observed default configs, and proposed-configs/ (build.py
  generates tiers and bench variants and fails on unknown keys;
  apply_variant.py applies a variant and merges options.txt).
- analysis/client-perf/bench/onion-bench/: bench-world datapack (scene
  teleports, Create grid, mob pen, sound storm, 120 s teleport tour).
- analysis/audit/: the static recipe/dependency audit, including gen_fixes.py,
  which generates the shipped Paxi datapack and was never tracked.
- phase0/: per-machine measurement harness (Steam Deck, 7700K/1060,
  6700K/1080 Ti).
- .pi/journal.md: running work log; read it first.

All of it is packwizignored, so nothing here ships to players.
2026-10-14 18:15:32 -04:00

283 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 0 — P2: i7-6700K / GTX 1080 Ti (Linux, Docker present)
Setup and measurement procedure for the CPU-and-RAM-bound machine in the Onion MC client
tuning fleet.
---
## Profile
| | |
| --- | --- |
| CPU | Intel i7-6700K, 4 cores / 8 threads, 4.0 GHz base / 4.2 GHz turbo (Skylake) |
| GPU | NVIDIA GTX 1080 Ti, **11 GB VRAM** (Pascal) |
| RAM | 16 GB total, **~8 GB occupied by Docker** |
| OS | Linux |
| **Binding constraint** | **CPU (main thread) + RAM/GC pressure** |
| **What this tier tests** | CPU-render and RAM/GC ladder steps on a capable GPU |
| **Expected DH answer** | **On, with the CPU/thread preset lowered — quality preset stays up** |
### The important inversion
This machine's GPU is the second-strongest in the fleet by a wide margin, and 11 GB of VRAM
is more than most current mid-range cards. **DH's GPU cost is not the problem here.** The
constraints are a 4C/8T Skylake main thread and a heap that has to fit in roughly 8 GB.
Consequence: for this tier, **turn DH's CPU/thread preset down, not its quality preset.**
That is the opposite lever from the other two machines, and it is the clearest example of
why the ladder cannot be a single global ordering.
### Standing constraint for this machine
> **Do not alter Docker or any other running process for the sake of these measurements.**
> Assume the existing load is constant and consistent, and treat it as a fixed property of
> this test rig.
That changes the guardrail from *"abort if RAM is low"* to *"record the baseline and verify
it stayed constant."* See Step 3 and Step 9.
---
## Shared measurement protocol
Applies to every machine in the fleet. Duplicated here so this document stands alone.
1. **Uncapped, vsync off** during measurement. Apply the FPS cap only *after* tuning.
2. **Metric is p99 frametime and 1% low, not average FPS.**
3. **Discard 10–15 s of warmup** per scene — JIT, chunk load, initial GC.
4. **Settle after any render-distance or DH change.**
5. **Three runs per configuration, report median and spread.**
6. **One variable per run.**
7. Guardrails: FPS limiter active, governor moved, or RAM headroom shifted materially →
the run is invalid.
---
## Step 1 — Preconditions
- [ ] Confirm the **proprietary NVIDIA driver** is in use. `nouveau` would invalidate both
the performance and the measurements.
```bash
nvidia-smi # must succeed
glxinfo -B | grep -E 'OpenGL renderer|OpenGL version'
```
- [ ] Confirm the compositor is not forcing vsync. If on X11/KDE, disable compositing for
the measurement session; on Wayland, disable any tearing/queueing control.
- [ ] Confirm the display resolution and refresh rate, and record them. Resolution is a
bigger GPU lever than most mod settings.
## Step 2 — GPU power state and throttling
Do this before every session. A GPU that is power-capped or thermally throttled produces
numbers that look like mod effects.
```bash
# Prefer maximum performance instead of adaptive clocks
nvidia-settings -a '[gpu:0]/GPUPowerMizerMode=1'
# Check for throttle reasons — SW Power Cap / HW Slowdown must be absent
nvidia-smi -q -d PERFORMANCE
```
Start background logging of VRAM, clocks, power and temperature. **Use this exact command
on the Windows machine too** — identical tooling on both NVIDIA boxes:
```bash
mkdir -p ~/mcbench/logs
nvidia-smi --query-gpu=timestamp,memory.used,clocks.sm,clocks.mem,power.draw,temperature.gpu,utilization.gpu \
--format=csv -l 1 > ~/mcbench/logs/gpu-$(date +%F-%H%M%S).csv &
```
`memory.used` is your VRAM series. On this machine it should stay comfortable; it is the
control against the 6 GB machine.
## Step 3 — Establish the noise floor (do this first)
Because Docker's load is assumed constant rather than eliminated, **you must measure the
noise before you can interpret any delta.** Otherwise you cannot tell a real 3% mod effect
from Docker doing something.
- [ ] Run the **same configuration, same scene, three times**, with no changes at all.
- [ ] Record p50/p95/p99 spread across those three runs.
- [ ] **That spread is your detection threshold.** Any later measurement smaller than this
spread is not evidence.
If the spread is large, Docker's activity is the first suspect. Record it as a known
limitation of this rig rather than trying to fix it.
## Step 4 — Record the RAM baseline
Do not change the running load — measure and freeze it.
```bash
free -h
cat /proc/meminfo | grep -E 'MemAvailable|SwapTotal|SwapFree'
```
- [ ] Record `MemAvailable` at session start.
- [ ] Repeat the reading before and after each block of runs. **If it drifts materially,
Docker's footprint changed and the runs are not comparable.** That is the check that
makes the "constant load" assumption falsifiable instead of merely asserted.
- [ ] Confirm no swap is being touched during runs:
```bash
grep -E 'pswpin|pswpout' /proc/vmstat # before and after; both should not move
```
Swapping during a run invalidates the p99 frametime numbers outright.
## Step 5 — CPU governor
The governor is a system setting, not a running process, and pinning it removes DVFS noise
on a 4C/8T Skylake. This is the one system-level change recommended on this machine.
```bash
sudo cpupower frequency-set -g performance
# or:
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
```
- [ ] Record the governor value before and after, and keep it identical across sessions.
- [ ] Revert to your normal governor when the measurement work is done.
> Also worth noting for the tier guide, independent of this benchmarking: a mild overclock
> on this CPU is a larger and cheaper win than most mod tuning. Measure at stock first so
> the baseline is comparable.
## Step 6 — MangoHud
```bash
sudo pacman -S --needed mangohud # or your distro's package
```
Config lives at `~/.config/MangoHud/MangoHud.conf`. Start from the packaged example
(`pacman -Ql mangohud | grep MangoHud.conf` to locate it) rather than a transcription, then
set:
```ini
output_folder=/home/<user>/mcbench/logs
autostart_log=1
log_duration=30
fps_limit=0
frametime=1
frame_timing=1
# percentiles — confirm the exact key/syntax in the packaged example
```
## Step 7 — Launcher and JVM
Use **Prism Launcher** (or ATLauncher) and launch from a terminal so the environment is
under your control.
**Java:** 21 — **the same JVM build as the other two machines**, to avoid a confound.
**Wrapper command** — Prism → *Edit Instance → Settings → Custom Commands → Wrapper
command*:
```
mangohud
```
Fallback if it fails to hook: `mangohud --dlsym`.
**JVM arguments** (identical across the fleet except `-Xmx`):
```
-Xmx6G
-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200
-XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC
-XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M
-XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4
-XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90
-XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32
-XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1
```
**Heap sizing rule for this machine:** `-Xmx` = min(6 GB, `MemAvailable` − 2 GB). With
~8 GB available that lands at 6 G; if the baseline reading is lower, lower the heap.
**Omit `-XX:+AlwaysPreTouch` on this machine.** It commits the entire heap up front, which
is exactly the wrong thing when Docker already holds half the RAM.
> **Read this before interpreting GC results.** Because heap is capped by Docker's
> footprint, GC pressure on this rig will be **higher than on an otherwise identical
> machine without Docker running.** This rig is therefore expected to *over-weight* the
> RAM/GC ladder steps and to show worse p99 lows than the same hardware would in the wild.
> Record it as a property of the rig; do not attribute it to a mod.
## Step 8 — Pin the in-game settings
Controlled variables — set once, record, do not change between runs unless the run is
testing that setting.
- Graphics: Fancy
- Render distance: 8
- Particles: All
- Clouds: Fancy
- Entity shadows: On
- Biome blend: fixed, recorded
- Mipmap levels: 4
- GUI scale: fixed number
- **Max framerate: Unlimited**
- **VSync: Off**
- FOV, resolution, fullscreen mode: fixed and recorded
## Step 9 — Verification run
- [ ] Launch, confirm the MangoHud overlay appears over Minecraft.
- [ ] Confirm a CSV lands in `~/mcbench/logs` with a frametime column.
- [ ] Confirm `nvidia-smi` logging is producing a CSV.
- [ ] Run the Step 3 noise-floor test and record the spread.
- [ ] Confirm `MemAvailable` and swap counters are stable across the three runs.
## Step 10 — Per-session checklist
- [ ] `nvidia-smi` works; power mizer set to max performance; no throttle reasons
- [ ] `nvidia-smi` background logging started
- [ ] Governor recorded (and pinned to `performance` if using that policy)
- [ ] `MemAvailable` recorded; swap counters checked
- [ ] Compositor vsync disabled
- [ ] MangoHud overlay visible, CSV output folder writable
- [ ] Noise floor re-established if the session is a new day
## Step 11 — Recording sheet
| Field | Example |
| --- | --- |
| Date / session | 2026-09-28-a |
| Machine | P2-6700K-1080Ti |
| Config ID | baseline / dh-cpu-preset-low / emf-off / … |
| Scene | A-base / B-terrain / C-gui |
| Run # | 1 / 2 / 3 |
| CSV file | |
| p50 / p95 / p99 frametime (ms) | |
| 1% low FPS | |
| Avg FPS | |
| VRAM peak (MB) | |
| Throttle flag | none / SW Power Cap / HW Slowdown |
| `MemAvailable` before / after | |
| Swap delta | must be 0 |
| Notes | |
---
## Machine-specific caveats
- **Docker is not removed, so RAM is a live variable that must be monitored, not assumed
away.** The Step 4 before/after check is what keeps the results honest.
- **This rig will over-weight RAM/GC ladder steps** relative to identical hardware without
Docker. Documented, not corrected.
- **Establish the noise floor before interpreting anything.** With a constant-but-unknown
background load, small deltas are unreadable until you know the spread.
- **CPU is the bottleneck, so CPU-side ladder steps are expected to show their largest
deltas here** — EMF/ETF and Fresh Animations, DH's thread preset, Sound Physics reverb,
LambDynamicLights. GPU-side steps may show almost nothing, and that is a real result, not
a failed measurement.
- **Pascal is a legacy driver branch.** Verify the driver is still current before drawing
comparisons against newer hardware.
- **11 GB VRAM means this is the fleet's control for "VRAM is not the constraint."**
Comparing this machine against the 6 GB GTX 1060 isolates GPU/VRAM effects, because both
machines share the same 4C/8T CPU class. If a knob you classified as CPU-render diverges
between the two, your classification is wrong — that is the taxonomy self-check.