Luanti logo

IRC log for #luanti-dev, 2025-12-23

| Channels | #luanti-dev index | Today | | Google Search | Plaintext

All times shown according to UTC.

Time Nick Message
00:16 user333_ joined #luanti-dev
00:21 SFENCE joined #luanti-dev
00:39 SFENCE joined #luanti-dev
00:54 nekobit joined #luanti-dev
01:29 behalebabo joined #luanti-dev
02:35 ivanbu joined #luanti-dev
03:00 SFENCE_arch joined #luanti-dev
03:51 user333_ joined #luanti-dev
03:52 SFENCE joined #luanti-dev
03:55 user333_ joined #luanti-dev
05:00 MTDiscord joined #luanti-dev
06:30 user333_ joined #luanti-dev
07:31 pgimeno joined #luanti-dev
08:26 ivanbu joined #luanti-dev
08:38 lhofhansl joined #luanti-dev
08:40 lhofhansl Why is the "loopcount >= initial_size" check needed here https://github.com/luanti-org/luanti/blob/master/src/servermap.cpp#L944?
08:41 lhofhansl I added more instrumentation to map-loading and found that repeatedly processing the same liquid queue is causing the severe slowdown.
08:42 lhofhansl Removing that part gets back to expected loading speeds. I get we do not want to do unbound processing, but perhaps we can limit this other ways.
08:47 sfan5 I assume it's a rate-limit, because it makes sure the queue is fully looked at at most once
08:51 sfan5 I think it's an oversight to not consider that initial_size may be very small
08:51 sfan5 so `loopcount >= std::max(100, initial_size)` is probably better
08:57 lhofhansl During mapgen of some ocean heavy scene, initial size is often around 1600, and the whole processed queue can be up 54000.
08:58 lhofhansl (That's for a whole chunk of 512000 nodes)
09:00 sfan5 well if this is happening on the emerge thread this limit should maybe not apply
09:02 lhofhansl When I measure the max liquid queue processing time (after removing that check) it never goes above 40ms on my machine, (Average settles somewhere between 5 and 15 ms)
09:03 lhofhansl Liquid processing is done on the main thread.
09:03 sfan5 in the emerge code, whatever
09:03 sfan5 but won't that lag the server anyway, since the env lock is held?
09:04 lhofhansl transformLiquids is called from AsyncRunStep
09:05 lhofhansl So, yes, it would lag the server more, but would allow for the maploading to not stall (in a busy loop, looking at the same blocks over and over, until the older blocks in the queue are finally processed).
09:06 lhofhansl That's the tradeoff.
09:06 sfan5 you mean map sending, not loading. still this is cool in singleplayer but not so cool in multiplayer
09:06 sfan5 you don't want to lag the server for everyone to speed up map loading for one guy
09:07 lhofhansl RemoteClient::getNextBlocks, yeah, sending.
09:08 lhofhansl Could check for number of clients.
09:11 lhofhansl It's just dumb how much CPU Luanti wastes, due to resetting the resent distance, and checking already sent blocks again.
09:16 lhofhansl Actually... Normal liquid queue processing goes up to 30ms on my machine (with the check in place). So this won't actually increase the lag a lot. To be safe we could lower liquid_queue_max bit.
09:18 lhofhansl Wait... Sorry, had the log still in there. Without any changes liquid processing is about 6ms on my machine.
09:21 sfan5 two thoughts: 1. maybe we could be smarter about the reset send distance thing in general
09:21 sfan5 2. but also could the time limit spent on liquids be made more dynamic without leading to more lag?
09:23 lhofhansl Definitely yes on 1. but that stuff is subtle. (I opened and closed various PRs on that :) ). 2. Yes, we just need to decide what is acceptable lag. Maybe instead of size bound, we can time bound liquid processing.
09:23 sfan5 3. it could also be possible to implement a "safe liquid scan" (that is thread-safe). it would only do things that can be done without lua/env callbacks. the idea is that this could be used in the emerge thread to get rid of most of the 54000 queue items, before doing the "critical" processing in the server thread
09:27 sfan5 I think for your PR it's best not to try too many things at once. So I'd suggest taking the wins from the local liquid queue, leaving the rest alone, and thinking about it in follow-up PRs.
09:44 lhofhansl Yeah... The local liquid queue for generated chunks only... But I'm not sure that works as I expected. I was looking at the queue process limits as an alternative.
09:45 lhofhansl That local queue has to be processed completely, or changes are lost.
09:54 sfan5 there is no need to lose the changes
09:56 sfan5 re 3: transformLiquids looks completely safe unless it decides that a node must change. that could be factored out, or a new implementation that implements "if source liquid surrounded by same sources, remove from queue" also sounds like an useful first pass that can be done thread-safely
10:00 lhofhansl I'll push a new update to the PR... Processing the whole queue for one chunk is quick (can't measure the difference actually).
10:02 lhofhansl have a look
10:10 lhofhansl I'll measure the maximal local chunk queue/loop count.
10:13 lhofhansl Since accumulated over 1s it would never go above 55k, and it could process 70 chunks/s (in my test) the per chunk max queue size should be less than 800.
10:22 sfan5 fwiw I did a quick test with skipping all liquid processing and while it makes the terrain loading noticably faster, it's not that slow without
10:52 lhofhansl It's very pronounced when running with a local server (which uses dedicated server step of 90ms.) and with larger viewing_range. Notice how a newly generated map just sites there... For many, many seconds, apparently doing nothing.
10:52 lhofhansl I added your suggestions.
10:55 lhofhansl There is still some unnecessary waiting where there's a mix of loaded and generated blocks, but it's much better. Hopefully an easy win.
10:56 lhofhansl As for thread-safety. transformLiquids accesses the map (getNode), so has to be under the envlock anyway.
11:00 sfan5 local liquid updates could be done with just the MapBlock/VManip and queue
11:01 lhofhansl And then record effects to neighboring blocks somewhere and process in the global queue?
11:07 sfan5 since liquid updates also cause Lua calls this is only feasible to clean the queue of nodes that don't change. but yes, the rest would go into the global queue
11:07 sfan5 <+sfan5> re 3: transformLiquids looks completely safe unless it decides that a node must change. that could be factored out, or a new implementation that implements "if source liquid surrounded by same sources, remove from queue" also sounds like an useful first pass that can be done thread-safely
11:07 sfan5 maybe ReflowScanner already skips these, dunno
11:11 Krock I find it interesting that the first thing I see in transformLiquids is that the positions are contained in a std::vector instead of std::set to avoid potential duplicates (if the code even allows that)
11:12 sfan5 m_transforming_liquid is an UniqueQueue<v3s16>
11:12 Krock oh I see. that's good.
11:49 YuGiOhJCJ joined #luanti-dev
13:05 user333_ joined #luanti-dev
13:18 user333_ joined #luanti-dev
13:28 user333_ joined #luanti-dev
13:35 SFENCE_arch joined #luanti-dev
13:59 Sheriff_U3 joined #luanti-dev
15:11 Sheriff_U3 joined #luanti-dev
15:43 SFENCE joined #luanti-dev
16:41 Desour joined #luanti-dev
17:51 SFENCE joined #luanti-dev
19:51 fluxionary joined #luanti-dev
19:55 SFENCE joined #luanti-dev
20:09 SFENCE joined #luanti-dev
20:09 user333_ joined #luanti-dev
20:10 user333_ joined #luanti-dev
20:13 user333_ joined #luanti-dev
23:17 mrcheese joined #luanti-dev
23:30 SFENCE joined #luanti-dev
23:36 panwolfram joined #luanti-dev

| Channels | #luanti-dev index | Today | | Google Search | Plaintext