mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-08-27 12:41:43 +00:00
Updated Docs, and Cortections
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
# 33 - Performance Tuning
|
||||
|
||||
Iris throughput is dominated by generation threads, mantle residency, pregen in-flight limits, cache sizes, and optional SIMD kernels. All knobs below live in `settings.json` under the Iris data directory unless noted. Settings overview: `03 - Configuration.md`. Pregen operations: `07 - Pregeneration.md`. Determinism must stay intact after tuning — verify with GoldenHash (`32 - Determinism & Goldenhash.md`).
|
||||
|
||||
## Where settings live
|
||||
|
||||
| Platform | Data directory | Settings file |
|
||||
|----------|----------------|---------------|
|
||||
| Bukkit-family | `plugins/Iris/` | `settings.json` |
|
||||
| Fabric / Forge / NeoForge | loader config `iris/` | `settings.json` |
|
||||
|
||||
Hotload behavior for settings follows `03 - Configuration.md`. After changing SIMD or thread-pool related keys, restart if values are read once at kernel install / pool creation.
|
||||
|
||||
## Performance section (`performance`)
|
||||
|
||||
| Key | Default | Role |
|
||||
|-----|---------|------|
|
||||
| `performance.simdKernels` | `true` | When true and `jdk.incubator.vector` is available, use vector kernels; otherwise scalar fallbacks |
|
||||
| `performance.mantleKeepAlive` | `30` | Mantle plate keep-alive window (seconds-scale residency control used by mantle lifecycle) |
|
||||
| `performance.mantleCleanupDelay` | `200` | Delay before mantle cleanup work |
|
||||
| `performance.trimMantleInStudio` | `false` | When true, studio worlds trim mantle more aggressively |
|
||||
| `performance.noiseCacheSize` | `1024` | Noise sample cache capacity |
|
||||
| `performance.resourceLoaderCacheSize` | `1024` | Pack resource loader cache capacity |
|
||||
| `performance.objectLoaderCacheSize` | `4096` | Object (`.iob`) loader cache capacity |
|
||||
| `performance.engineSVC.useVirtualThreads` | `true` | Engine service uses virtual threads when true |
|
||||
| `performance.engineSVC.forceMulticoreWrite` | `false` | Force multicore write path |
|
||||
| `performance.engineSVC.priority` | `Thread.NORM_PRIORITY` | Clamped to valid Java thread priorities |
|
||||
| `performance.engineSVC.parallelism` | `-1` | `>0` caps at `2 * CPU`; `≤0` uses `ceil(sqrt(CPU))` |
|
||||
|
||||
Larger loader caches trade heap for fewer pack disk/JSON reloads during generation. Raise `objectLoaderCacheSize` when pregen is object-heavy and the pack is large; lower caches if heap pressure shows retained pack data.
|
||||
|
||||
## Pregen section (`pregen`)
|
||||
|
||||
| Key | Default | Role |
|
||||
|-----|---------|------|
|
||||
| `pregen.runtimeSchedulerMode` | `AUTO` | Bukkit pregen scheduler mode: `AUTO`, `PAPER_LIKE`, `FOLIA` (Folia runtime always resolves to Folia scheduling) |
|
||||
| `pregen.paperLikeBackendMode` | `AUTO` | Paper-like backend: `AUTO`, `TICKET`, `SERVICE` |
|
||||
| `pregen.chunkLoadTimeoutSeconds` | `15` | Clamped 5–120 |
|
||||
| `pregen.timeoutWarnIntervalMs` | `500` | Minimum 250 ms between timeout warnings |
|
||||
| `pregen.saveIntervalMs` | `30000` | Clamped 5_000–900_000 |
|
||||
| `pregen.maxResidentTectonicPlates` | `96` | Soft cap (effective floor 16) on resident mantle tectonic plates |
|
||||
| `pregen.mantleBackpressureWaitMs` | `25` | Clamped 5–1000; wait when mantle backpressure engages |
|
||||
| `pregen.mantleBackpressureTimeoutMs` | `60000` | Clamped 5_000–600_000 |
|
||||
| `pregen.moddedPregenInFlight` | `0` | `0` = auto `clamp(16, cpu*2, 48)`; positive values clamp to 1–512 |
|
||||
|
||||
Effective resident plates also scale with world height and process heap: higher worlds and smaller heaps reduce the effective plate count (minimum 16). If pregen stalls with mantle pressure, lower concurrency first, then reduce `maxResidentTectonicPlates`, or raise heap so the byte budget allows more plates.
|
||||
|
||||
Related world flag: `world.globalPregenCache` (default `false`) — global pregen cache behavior; see `03 - Configuration.md` / `07 - Pregeneration.md`.
|
||||
|
||||
## Concurrency helpers (`concurrency`)
|
||||
|
||||
`IrisSettingsConcurrency` exposes derived counts (not all are free-form JSON knobs with independent storage in every build path):
|
||||
|
||||
- World-gen style parallelism floors at `max(2, availableProcessors)`.
|
||||
- IO parallelism floors at `max(2, availableProcessors / 2)`.
|
||||
|
||||
Prefer pregen in-flight limits and `engineSVC.parallelism` for production tuning rather than inventing extra thread pools outside settings.
|
||||
|
||||
## SIMD
|
||||
|
||||
**Note:** Broader SIMD coverage (including full noise-kernel wiring through production worldgen) is actively being worked on. Array kernels used on some hot paths already honor `performance.simdKernels` when the incubator Vector API is available; treat noise SIMD as incomplete until that work lands.
|
||||
|
||||
Runtime selection (`SimdSupport`) today:
|
||||
|
||||
1. If `performance.simdKernels` is false → scalar kernels.
|
||||
2. Else if module `jdk.incubator.vector` is present and vector kernel classes load → vector kernels for **array ops** used in some generation hot paths (for example `roundToInt` via `ChunkedDoubleDataCache`, carving paths via `MantleCarvingComponent`).
|
||||
3. Else → scalar kernels; startup log tells the operator to add `--add-modules jdk.incubator.vector`.
|
||||
|
||||
2D fractal noise vector kernels exist (`VectorNoiseKernels2D`) and are gated to CPUs where `double` vector width is profitable (≥ 4 lanes). That path is selected by `SimdSupport.noiseKernels2D()` but is **not** the primary wired worldgen path yet.
|
||||
|
||||
JVM flag (required for vector API incubator):
|
||||
|
||||
```
|
||||
--add-modules jdk.incubator.vector
|
||||
```
|
||||
|
||||
Server start scripts and Gradle run configs for Iris already pass this where Iris launches the JVM. Standalone microbench: `tools/simd-bench/` (`./run.sh` or `run.bat`). That tool force-measures kernels even when Iris would gate noise SIMD off (for example Apple Silicon 2-lane NEON). Microbench speedups do not guarantee end-to-end pregen gains.
|
||||
|
||||
To A/B SIMD on a full server: set `performance.simdKernels` false, restart, measure pregen chunks/s, re-enable, restart, remeasure. Confirm GoldenHash unchanged (`32 - Determinism & Goldenhash.md`).
|
||||
|
||||
## Operator pregen modes that affect load
|
||||
|
||||
| Mode | Platform | Effect |
|
||||
|------|----------|--------|
|
||||
| Default pregen | All | Concurrent generation within platform scheduler limits |
|
||||
| `serial=true` | Bukkit Paper-compatible only | Strict one-in-flight chunk pregen; rejected on non-Paper serial support |
|
||||
| `sync` / in-flight flags | Modded | Synchronous or capped async pregen; see `07 - Pregeneration.md` |
|
||||
| `moddedPregenInFlight` | Modded | Caps concurrent pregen chunk work |
|
||||
|
||||
For profiling and determinism isolation, prefer serial/sync one-in-flight runs. For production throughput, use default concurrency and raise heap before raising mantle plate caps.
|
||||
|
||||
## Practical tuning order
|
||||
|
||||
1. **Heap and GC** — give the process enough heap for pack caches + mantle plates (release smoke used 8 GiB heap on large pregens; size to hardware).
|
||||
2. **Confirm SIMD module** — check startup log for `SIMD: vector kernels enabled` vs scalar message.
|
||||
3. **Pregen concurrency** — use default; only lower in-flight / use serial when CPU saturated or region scheduling warns.
|
||||
4. **Mantle residency** — if backpressure timeouts appear, reduce `maxResidentTectonicPlates` or pregen speed; increase heap if plates thrash.
|
||||
5. **Caches** — raise object/resource caches when the same objects reload repeatedly; lower if heap retains too much after pregen.
|
||||
6. **engineSVC.parallelism** — set an explicit positive value only after measuring; `-1` already scales with CPU via `ceil(sqrt(n))`.
|
||||
7. **Never “tune” by changing pack content** for performance without a GoldenHash re-baseline — pack edits change terrain.
|
||||
|
||||
## Measurement checklist
|
||||
|
||||
Record for each experiment: pack identity, seed, radius, serial/sync flags, JVM version/flags, heap, CPU, `settings.json` performance/pregen excerpts, chunks/second, duration, failed chunks, peak heap, and GoldenHash combined value. Reject optimizations that change hashes unless the behavior change is intentional and documented. Larger release-style baselines (5k–10k chunks, JProfiler) are tracked in `87 - Maintainer - Release Readiness.md`.
|
||||
|
||||
## Offline tools
|
||||
|
||||
| Tool | Command | Use |
|
||||
|------|---------|-----|
|
||||
| Generation probe | `./gradlew :probe:genProbe -PprobePack=…` | Headless engine generate; not a throughput benchmark |
|
||||
| Classload probe | `./gradlew :probe:run` | Purity/classload gate |
|
||||
| SIMD microbench | `tools/simd-bench/./run.sh` | Kernel-only scalar vs vector timing |
|
||||
|
||||
Smoke procedures that combine pregen and GoldenHash: `31 - Operator Runbooks & Smoke Tests.md`.
|
||||
Reference in New Issue
Block a user