Repository navigation
Conversation
1. `ElytraBehavior` needs a thread safe `BlockStateInterface` for the solver 2. The cache in `BlockStateOctreeInterface` is not thread safe
ZacSharp's 74dd28b2, ported as it is, in place of the #5156 port below: the cache goes back to three plain fields and is no longer shared. Every reader makes its own through getBoi(), which also puts it in a WeakHashMap-backed set that the writer walks under the write lock to clear them all; the solver context carries one, and the obstacle check makes one per tick. The fork's invalidate() is what the walk calls. The thread-safe BlockStateInterface stays, since both PRs make that change. Pushed so that CI's in-world test flies the four elytra stages with this PR's code too. Co-Authored-By: Claude Mythos 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WyYJgBP5vLVRjrcXVvTizn
|
hey sorry I dropped the ball on this/the earlier issue, I did a bunch of benchmarking on several systems that I can share. ill make a comment soon but I need to make sure the numbers and verdict are right |
…waway) A stage passes or fails on what the game thread does, so an exception on a background thread -- the one cabaletta/baritone#5155's WeakHashMap could throw on the write executor -- never fails the test and never reaches the job log, which only greps the stage lines out of autotest.log. Count and print them after the verdict so the flight says so either way. Co-Authored-By: Claude Mythos 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WyYJgBP5vLVRjrcXVvTizn
|
Here they are as promised! I flew the fork's two in-game nether elytra test stages (under and above the roof) with every
Raw JMH json and gc profiles: https://github.com/0Mattias/cheesecake/actions/runs/40240588255. The flights with this PR's code: https://github.com/0Mattias/cheesecake/actions/runs/40257752077 and https://github.com/0Mattias/cheesecake/actions/runs/40259191833. Two things in the code that Claude noticed:
I'd probably drop the registry entirely. Every boi here is used inside a single read lock hold (obstacle check: created and used under the lock; main thread solve: ElytraProcess holds the read lock around Numbers per machine (1.21.4)Each column is a different machine, so only compare within a column. Each cell is above the roof / below the roof. Flights: above the roof 853 solves and 2,980,424 lookups over 21.6 s, below the roof 1,022 solves and 4,172,079 lookups over 24.9 s. JMH, 3 forks; confidence intervals and the 26.3 tables are in the run's json and job summaries. One thread. First row ns per call, the rest relative to it:
Two threads at once, ns per call (the per-solver cache gives each thread its own):
The record is 24 bytes per chunk change (about 1.5 B per call here). Today's code boxes a Long of the same size for the map key on each change, which the JIT removed in some runs and not others. |
Had this sitting in my workdir for more than a week and didn't get around to benchmark it, so I'll just put this up as a draft.
Does the same as #5156 but maybe faster by avoiding implicit synchronization and some allocations. However this is more complicated and has a footgun more (reusing a
boion the wrong thread), so unless someone benchmarks this to be faster, #5156 is the way to go.Draft due to missing benchmark.
Fixes #5136