Server: feed the chunk workers between ticks while players' chunks load
A server thread (single player's, a LAN host's, a dedicated server's) ran `streaming.update` once a tick, and `schedule_generation` keeps at most three load or generate jobs per worker in flight. Joining a world was capped at about six columns a tick (120 a second with two workers) while the workers idled most of each tick. Vanilla's server runs its chunk tasks while it waits for the next tick (`MinecraftServer.waitUntilNextTick`). `pump_pregen`, now `pump_chunks`, already did that for a /pregen task and force-loaded chunks; it now also pumps while the players' chunks are in flight, except while the server is paused or a respawn search waits for a chunk (its area is only asked for by the tick's own update). Mac mini, --profile fast, offscreen, seed 1234, RD 12, server thread, medians of 3, all 637 view columns in and meshed once: 2 workers: create 8.05 -> 3.57 s, reload 3.72 -> 1.42 s 4 workers: create 4.97 -> 2.16 s, reload 2.23 -> 1.27 s Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -227,7 +227,7 @@ impl Game<'_> {
|
||||
}
|
||||
|
||||
/// Whether the level in place has a running task, which the server pumps
|
||||
/// between its ticks (`pump_pregen`).
|
||||
/// between its ticks (`pump_chunks`).
|
||||
pub(in crate::game) fn pregen_runs_here(&self) -> bool {
|
||||
self.cmds
|
||||
.pregen
|
||||
@@ -243,11 +243,19 @@ impl Game<'_> {
|
||||
/// Keep the workers fed until `until`: collect what they finished and
|
||||
/// hand them the next jobs as soon as each one is done, rather than once
|
||||
/// a tick.
|
||||
pub(in crate::game) fn pump_pregen(&mut self, until: Instant) {
|
||||
pub(in crate::game) fn pump_chunks(&mut self, until: Instant, paused: bool) {
|
||||
// Force-loaded chunks too: decorating in vanilla's order, a chunk
|
||||
// waits for its neighbours far more often than once a tick allows.
|
||||
// And the players' chunks while they load, as vanilla's server runs
|
||||
// its chunk tasks while it waits for the next tick
|
||||
// (`MinecraftServer.waitUntilNextTick`): once a tick, a few jobs per
|
||||
// worker (`schedule_generation`) capped joining a world at about 120
|
||||
// columns a second with two workers, the workers idle most of the
|
||||
// time. Not while a respawn search waits for a chunk: its area is
|
||||
// only asked for by the tick's own `update_world`.
|
||||
let players = !paused && self.spawn_wait.is_empty();
|
||||
while self.pregen_runs_here()
|
||||
|| (!self.streaming.forced.is_empty() && self.streaming.busy())
|
||||
|| ((players || !self.streaming.forced.is_empty()) && self.streaming.busy())
|
||||
{
|
||||
let now = Instant::now();
|
||||
if now >= until {
|
||||
|
||||
@@ -408,9 +408,9 @@ impl Game<'_> {
|
||||
}
|
||||
*next += self.clock.tick_duration();
|
||||
if *next > now {
|
||||
// A `/pregen` task or force-loaded chunks keep the workers fed
|
||||
// until the next tick.
|
||||
self.pump_pregen(*next);
|
||||
// The chunks loading (the players', force-loaded ones, a
|
||||
// `/pregen` task) keep the workers fed until the next tick.
|
||||
self.pump_chunks(*next, paused);
|
||||
let now = Instant::now();
|
||||
if *next > now {
|
||||
std::thread::sleep(*next - now);
|
||||
|
||||
@@ -40,7 +40,7 @@ start it again and the chunks already saved load instead of generating.
|
||||
(`DecorationOrder`), and this makes a task decorate in the same order however its jobs are timed and
|
||||
shared among the workers: the same seed gives the same chunks.
|
||||
- Between server ticks the server waits for the workers' results and hands out the next jobs at once
|
||||
(`Streaming::wait`, `pump_pregen`), instead of once a tick: a chunk passes through five jobs
|
||||
(`Streaming::wait`, `pump_chunks`), instead of once a tick: a chunk passes through five jobs
|
||||
(generate, decorate, finish, light, save), each needing its neighbours' earlier ones.
|
||||
|
||||
The chunks of the band's outer ring are finished (FULL) but not lit, as at the edge of what a player has
|
||||
|
||||
Reference in New Issue
Block a user