News for hackers. Stuff that matters.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by viraptor on Tuesday June 27, 2023 @02:53AM (#36489697)
I know this isn't the point of Folia's test, but:

> During the period when 1,000 players were online, we reached a maximum of ~7.9GB/s heap allocation and our GC was hovering around 2-3GB/s when averaged over a minute.

As someone who dealt with soft-realtime telephony stuff, this makes me want to scream in horror. It seems like the platform really hurts the performance here. In an average second with that many players, most (all?) of them will not do any action apart from changing their position. (Just moving around would ideally only use preallocated per-player space only; extra in-game events, npc AI, etc. could still use some allocs) It's great Folia can get more out of the bad situation, but... oofff.

(not a criticism of Minecraft by the way, it's better to be popular and inefficient than not exist - I just didn't realise quite how much overhead there is due to the runtime)

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by skerit on Tuesday June 27, 2023 @03:15AM (#36489830)
> In an average second with that many players, most (all?) of them will not do any action apart from changing their position

The world is not static though. Each player loads in a lot of living entities (monsters/animals/...) and block entities (furnaces, redstone, ...) that all need to update. There's some overlap of course, though in a game like Minecraft where there's a near infinite world to explore that overlap is smaller than you would think.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by Cthulhu_ on Tuesday June 27, 2023 @04:09AM (#36490199)
Well yeah but that's a process that can run independently from player movement and (I guess?) can be a highly asynchronous and paralellised process.

(note: armchair remark, I honestly haven't a clue)

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by tehbeard on Tuesday June 27, 2023 @04:35AM (#36490372)
Not really.

Block entities (those with complex data, like inventories) can be read/interacted with by redstone (a regular-ish set of blocks in terms of data), which can then trigger a piston or dispenser (which changes the world), and said piston or dispenser can then interact with the players movement, pushing them, or hitting them with an arrow, or dispensing water that changes their movement.

Same again for non player entities, but also factor in their AI having to adjust pathing based on the world changing.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by bakugo on Tuesday June 27, 2023 @04:42AM (#36490419)
> can be a highly asynchronous and paralellised process

It really can't, though. Parallelization is the enemy of consistent game mechanics, especially in a complex sandbox game like minecraft. There are tons of things that interact with each other in minecraft's world - if you just tick everything at arbitrary times, those interactions cease to be deterministic and might break entirely unless you write a ton of spaghetti code to deal with every edge case. Redstone in particular is the best example of a mechanic that heavily relies on the synchronous nature of the game logic loop.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by viraptor on Tuesday June 27, 2023 @05:01AM (#36490540)
> Each player loads in a lot of living entities (monsters/animals/...) and block entities (furnaces, redstone, ...) that all need to update.

Sure, but that list of entities in the area is close to static (apart from crazy redstone magic). One would expect them to be pooled and not have many allocations for each tick.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by ghosty141 on Tuesday June 27, 2023 @05:11AM (#36490610)
But each has to do a lot of stuff. People on such big servers build farms with hundreds of mobs dropping thousands of items which then go through redstone sorting systems.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by zimpenfish on Tuesday June 27, 2023 @05:20AM (#36490668)
> People on such big servers build farms

~Normally, yeah, but Folia is based on Paper which, AFAIK, is known for its unreliability when it comes to the technical aspects of Minecraft (ie redstone and farms.) Even your bog-standard simple item sorter is apparently a bit hit-or-miss on Paper.~

Edit: Possibly outdated info, things sound better re: technical Minecraft support on Paper now according to 'ocelotpotpie.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by ocelotpotpie on Tuesday June 27, 2023 @05:27AM (#36490711)
The hardcore technical folks seem to prefer things that don't alter the vanilla mechanics quite as much as Paper, it's true. But FWIW there are lots of farm and redstone designs that work reliably on Paper.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by zimpenfish on Tuesday June 27, 2023 @05:27AM (#36490718)
> But FWIW there are lots of farm and redstone designs that work reliably on Paper.

Ah, good to know - been a long while since I last tried Paper.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by ghosty141 on Tuesday June 27, 2023 @05:47AM (#36490833)
Its fine for most stuff the average player does. I wouldnt run a redstone computer on it but I personally never had an issue with my farms.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by nottorp on Tuesday June 27, 2023 @10:09AM (#36493030)
> Even your bog-standard simple item sorter is apparently a bit hit-or-miss on Paper.~

My simple sorters have been working just fine(tm) on Paper in the last (>5) few years.

I do hear co players having occasional problems with fancier set ups, but most automation just works.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by veave on Tuesday June 27, 2023 @05:24AM (#36490693)
The kind of mental gymnastics that people do here to justify needing 8 GB of RAM with a turnover of 3 GB per minute to handle 1000 users.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by Rapzid on Tuesday June 27, 2023 @05:34AM (#36490775)
Per second.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by kaba0 on Tuesday June 27, 2023 @08:02AM (#36491660)
It is definitely more than required, but let’s not go to the other end, it is neither a static html page.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by viraptor on Tuesday June 27, 2023 @05:51AM (#36490850)
I wouldn't say "each has to do a lot". There's a few trivial behaviours usually. Especially if you know what behaviours are common, you can optimise entity lists for that.

But that's not even what we're talking about here. This was a short-lived test server with new environment, not huge farms. The super high GC stats we see here are the baseline behaviour. More complex scenarios will push this even more.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by Kuinox on Tuesday June 27, 2023 @08:06AM (#36491684)
Thousands of items is small. Factorio doesn't need that amount of RAM when it routinely handle dozen of thousands of items every ticks.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by gjsman-1000 on Tuesday June 27, 2023 @11:53AM (#36494606)
Remember Minecraft is written in Java, not C++. The Bedrock version is written C++ but has only experimental, very rough native server software that is almost never used.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by ElectricalUnion on Tuesday June 27, 2023 @08:08PM (#36500499)
> Factorio doesn't need that amount of RAM when it routinely handle dozen of thousands of items every tick.

It might not inefficiently allocate all that RAM every tick, but it still has to scan a lot of RAM, and write to a bunch of locations to update the game state.

It loves CPUs with huge caches because of that.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by hwillis on Tuesday June 27, 2023 @08:55AM (#36492075)
The world is 100k blocks to a side, with players split up in groups of 20 over the whole thing. Since allocation rose steadily from 35 min and peaked from 47 to 63 minutes, I'm guessing they were spread out pretty widely.

There were 113 regions in one of the pictures- call it 9 players per region, with ~927 live unique chunks (8x8 chunks for 9 players ~=566, plus a 19x19 area around the world origin thats always loaded). From what I can tell a Minecraft block is a bit over 10 kB. So ~10 MB per region.

If each thread is allocating 10 MB for each region on each tick (which the screenshot shows is 8 ticks per second) *that would work out to 8.6 gigabytes per second*. IMO, that's too close to be a coincidence- I'm thinking there are a lot of shared chunks per region, but the threads are copying significant amounts of data by value or they just have an absurd overhead.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by jandrese on Tuesday June 27, 2023 @03:14AM (#36489825)
The Minecraft Java version is notorious for thrashing memory. It allocates and discards objects at an incredible rate, even when the player isn't doing anything. The server has a GUI where you can watch the memory allocation with its distinctive sawtooth pattern.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by half-kh-hacker on Tuesday June 27, 2023 @03:35AM (#36489955)
I'm excited for Project Valhalla to affect Minecraft performance; a lot of the temporary allocations are things like BlockPos objects (a Vec3i, basically) and VoxelShapes (a tree of axis aligned bounding boxes; so, like, an array of a struct that's six f64s) which seem ripe for becoming value objects that are inlined by HotSpot instead of living on the heap
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by grishka on Tuesday June 27, 2023 @03:43AM (#36490014)
Why not pool these objects? I'm primarily an Android developer and it's a well-known easy optimization on Android to avoid short-lived objects as much as possible, but especially during drawing and other actions that run every frame. You just don't use the word "new" in onDraw and other related methods. Android Studio would even warn you if you do.

But then the new APIs in JDK itself are designed such that you have to allocate loads of short-lived small objects. I was told that HotSpot does deal with them reasonably well to avoid them degrading the performance, but apparently it isn't very good at it?

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by SirYwell on Tuesday June 27, 2023 @04:06AM (#36490178)
Allocation is typically really cheap, maintaining pools for objects would likely have more overhead. And while collecting garbage takes resources too, it's heavily concurrently, especially in GCs like Shenandoah and ZGC. So instead of more overhead due to pooling on the thread that uses the objects, you have more overhead on a different thread during garbage collection.

So while it makes sense to avoid unnecessary allocations by using different APIs (e.g. not creating Streams in hot paths), pooling brings far more new problems with it. It might make sense for large objects, but generally requires in-depth analysis to make sure it actually helps.

Also, when plugins come into the equation, you need to make sure that those can't modify objects they aren't meant to modify, which involves copying of objects. Additionally, some objects have different representations in the API (what's used by plugins) vs the implementation (what's used by vanilla minecraft), so converting between those representations is another source of allocations.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by tjoff on Tuesday June 27, 2023 @04:21AM (#36490284)
Pooling would have been more overhead than allocation + deallocation? Do you have any relevant readings?

No idea how to do it in java but a few pointers ought to be enough. You can also omit clearing the memory area between allocations for things that aren't security sensitive, if that is done in java, which I would assume.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by SirYwell on Tuesday June 27, 2023 @04:55AM (#36490504)
Allocation + deallocation might have more overhead together. I'll try to rephrase: Requesting an object from a pool might have more overhead than allocating a fresh object, and deallocating the object doesn't happen on an application thread but on a GC thread (depending on the GC, obviously). Alexksey Shipilev has good resources how GCs in HotSpot typically allocate objects (https://shipilev.net/jvm/anatomy-quarks/4-tlab-allocation/).

There definitely are scenarios where pooling might make sense, but basically the low hanging fruits in that area in minecraft are already reaped.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by tjoff on Tuesday June 27, 2023 @06:09AM (#36490963)
I got that, and thanks for the link. But I'm not convinced a pool would have more overhead. It is basically the same thing (not really, but then again, pretty much) just you can encode more information about the usage than a general GC can possible do.

For sure there are other tradeoffs, and whether it is worth it. But when we actually see many GB/s that is not cheap even if you are able to offload to other cores.

The article also concludes:

>It is funny to consider that having TLABs is the way to experience more frequent GC pauses, just because the allocation is so damn cheap!

Sounds like a nightmare, the problem just snowballs, because now you'll be tempted to get into GC tuning.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by jandrese on Tuesday June 27, 2023 @01:23PM (#36496002)
Seems like there should be a performance benefit from not constantly blowing out your L2 cache. If you can keep your object pool hot there should be quite a bit of performance to be gained. The downside is that this would require active memory management (explicitly freeing the objects when you're done with them) and if you have that why bother programming in a GC language in the first place?
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by zelos on Tuesday June 27, 2023 @07:53AM (#36491589)
For short lived objects, heap allocation is probably about as fast as allocating on the stack. By pooling you can end up moving objects out of the fast eden space into older generations.

I worked on optimising a java library a few years back and one of the bigger speed ups was removing all the object pooling code.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by tjoff on Tuesday June 27, 2023 @08:14AM (#36491748)
But that means that the pools still use the GC? If so then I fully agree. But the point of a pool in my mind would be to reuse the memory rather than allocate+deallocate it.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by fzeindl on Tuesday June 27, 2023 @05:07AM (#36490580)
Agreed. Allocation is pretty cheap, but it can still be slowed by an order of magnitude by two things:

1. by using finalizers

2. by using object initialization blocks

If you avoid these two problems you get nano-second performance, because the JVM does not need to run code during object creation and GC.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by ohgodplsno on Tuesday June 27, 2023 @03:40AM (#36489994)
Minecraft Java used to allocate over 200MB/s per player when moving, and just 50MB/s when static. A lot of it stems back from Minecraft 1.8, where code was updated to take a BlockPos(float x, float y, float z) class instead of just (float x, float y, float z). Pretty much every single object in the game has to deal with its position. Millions of objects allocated per frame, only to be discarded later. Along with a looooot of other questionable choices. It's not even a runtime problem: you'd have the same issues free()'ing that memory on your own. Just stop allocating so damn much.

But then again, Notch never claimed to be a great programmer.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by starlevel003 on Tuesday June 27, 2023 @03:42AM (#36490005)
the post-1.8 codebase awfulness has nothing to do with the source programmer. hell, by 1.13, the game had practically been rewritten at least once over.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by phito on Tuesday June 27, 2023 @03:44AM (#36490022)
Just use a struct... Oh wait, Java does not have structs....
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by grishka on Tuesday June 27, 2023 @03:50AM (#36490067)
Yet.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by mike_hearn on Tuesday June 27, 2023 @04:38AM (#36490397)
IIRC the introduction of BlockPos post-dates Notch. The style of just passing three floats around was his original style.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by le-mark on Tuesday June 27, 2023 @06:58AM (#36491254)
Notch was well aware of the issues around allocating a lot of small objects in Java. He used to write 4k games with a byte code assembler. Implying technical knowledge of the platform was not the problem.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by Pannoniae on Tuesday June 27, 2023 @07:39AM (#36491503)
Notchian code ran way better than modern MC - even though it used completely obsolete OpenGL 1.1 fixed-function calls.

They've upgraded to OpenGL 3 and shaders now; but the game's memory and CPU usage is through the roof with inconsistent performance and huge lagspikes.

Most of this is caused by utterly spurious and unneeded allocations; stream code on hot paths and complete overengineering and abstractions totally unfit for purpose. By that I mean heavy usage of inheritance and indirection in rendering code, and horrible memory wasting with vertex data. (Most things are full floats even if they could be packed and in some cases, even duplication of the same data due to bad data design)

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by kaba0 on Tuesday June 27, 2023 @07:59AM (#36491635)
Do you have any source for that? It seems questionable at best. Also, depending on where it is used, Java deals very well with indirect calls, it doesn’t have the same cost as, say, a C++ virtual call.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by Pannoniae on Tuesday June 27, 2023 @09:37AM (#36492529)
Source for which section? I am basing this on mostly my experience and codedigging - I don't think there are many written sources about observing this other than anecdotes on forums or reddit or whatever.

With that being said, I'm happy to investigate in detail if you can tell which parts you are interested in.

You are right, the JVM has many optimisations built in to de-virtualise calls and avoid allocations and the such, but if you abuse it, the JIT will give up. I don't think any JIT will de-virtualise or perform escape analysis on 5-6 layers of indirection with branching.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by winrid on Tuesday June 27, 2023 @03:51AM (#36490071)
This is not an issue with the runtime. If anything, the JVM is handling this really well.

The problem is code like:

while(game_running) { position = new Box(x,y,z) }

instead of reusing objects:

while(game_running) { position.set(x,y,z) }

plus, Minecraft is not static! There are many thousands of other things moving and changing state in the world.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by creatonez on Tuesday June 27, 2023 @04:04AM (#36490159)
An age old question... Is the code wrong for not being optimal, or is the compiler/JIT wrong for not optimizing it? I've seen optimizing compilers like clang, gcc, rust optimize constructs similar to this to the same machine code. Ideally you want your high-level stuff that makes code easier to understand to be completely transparent and not have a performance impact when the code actually runs.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by mike_hearn on Tuesday June 27, 2023 @04:36AM (#36490383)
Neither is wrong, and there's very likely a lot of low hanging JVM performance fruit here still to claim.

Right now they're in a bit of a transitional period. Since a few weeks ago the most obvious thing to try is using the latest Oracle GraalVM with ZGC. ZGC is a pauseless GC like Shenandoah and the Graal compiler is a lot better at escape analysis and removing allocations than the stock C2 compiler especially now Oracle made the enterprise compiler free to use.

The main problem is going to be that ZGC Generational is not quite launched yet. Without generational GC it may not be able to keep up with those very high allocation rates, even with a better compiler reducing them down again. Generational ZGC should be in Java 21 but then you'd have to wait for GraalVM to catch up. So, probably it's worth trying that combination in the next six months or so.

Whilst I don't know about ZGC vs Shenandoah, the performance improvements from using Graal EE over C2 can be large even for Java (the wins are much bigger still for other higher level/more dynamic languages). But the Minecraft community isn't really known for adopting the latest JVM tech. They're pretty conservative.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by winrid on Tuesday June 27, 2023 @04:08AM (#36490189)
For my simple case, it would. Generally, the code around the allocation is complicated so maybe it's not getting optimized for some reason. Or maybe the object is passed through some complicated path... or maybe it's added to a list and then cleared at the end of the frame...
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by viraptor on Tuesday June 27, 2023 @04:57AM (#36490513)
> This is not an issue with the runtime

Yes. But no. But yes.

The code couldn't been written better to allocate less. But the runtime encourages cheap allocations you don't think about. But the runtime could provide/encourage tooling that makes it hard to make that mistake. But...

It all overlaps. Sure, JVM is cool and handles it, but also what JVM is influenced how people instinctively used it.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by winrid on Tuesday June 27, 2023 @11:10AM (#36493996)
Most people don't write Java games this way. If you look at any libgdx code examples people cache objects and use polling - you don't know how modern a VM the user will have especially on Android.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by gghh on Tuesday June 27, 2023 @05:20AM (#36490669)
Do you think a minecraft server (and multiplayer game servers in general) can benefit for running on a soft-realtime OS like Linux with the PREEMPT_RT patch?

Games often use their tick rate (iterations of the event loop per second) as a quality metric, and an rt OS should favor preemption and low scheduling latency over throughput... so maybe that should give a more fluid experience?

But the bottleneck for minecraft seems to be in memory allocations, so an OS that can schedule threads rapidly may not change much after all.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by viraptor on Tuesday June 27, 2023 @08:20AM (#36491791)
First, Minecraft would have to actually support multithreaded work properly. Here the issue is just plain throughput / computation. RT usually makes things slower, but more predictable. MC needs to go faster first.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by 9659 on Tuesday June 27, 2023 @09:16AM (#36492267)
it all depends on if you want the tick time to equal the wall clock time.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by intelVISA on Tuesday June 27, 2023 @05:28AM (#36490722)
Well, Java isn't really used for perf critical workloads to be fair.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by wongarsu on Tuesday June 27, 2023 @07:30AM (#36491435)
I'd rephrase that as "Java usually isn't the first choice for perf critical workloads". It's still a very performant language if used correctly (outperforming C in some benchmarks where the JIT can shine), and used for lots of performance critical stuff.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by kaba0 on Tuesday June 27, 2023 @07:56AM (#36491616)
Java is absolutely used for perf critical workloads, hell, I am fairly sure that there are no runtime in existence that would handle that load of memory pressure better - of course the problem is sort of self-made, not every allocation should have to be done in the first place in this case.

But Java is heavily used in high-frequency trading, is the backbone of many cloud infrastructures and it is such a large platform that there are plenty of small niches where it is used and performance is important.

Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by intelVISA on Tuesday June 27, 2023 @10:25AM (#36493270)
True, though in any competitive shop it's still second to C++, as they can afford it.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by kaba0 on Tuesday June 27, 2023 @11:00AM (#36493858)
Isn’t the niche where truly insane latencies are required absolutely dominated by ASICs and a general purpose CPU is way out of the picture?
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by intelVISA on Tuesday June 27, 2023 @11:14AM (#36494055)
I believe so
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by madduci on Tuesday June 27, 2023 @06:19AM (#36491033)
Has anyone already tried to use GraalVM with it? Cool would be trying to do a native compilation and compare the performance
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by tuetuopay on Tuesday June 27, 2023 @08:04AM (#36491675)
That's a sample size of one, but I did try it once and it ended up being basically the same. HotSpot took a measurable amount of time to reach GraalVM performance (in the minute if memory serves), but once the hot path got JITed, they were basically on par. Since a minecraft server is (usually) a long-lived process, it does not matter in the end.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by polski-g on Tuesday June 27, 2023 @10:20AM (#36493182)
I've tried different JVMs, different garbage collectors, etc, etc. They all make negligible difference.
Re:Breaking the Limits: How Folia Made 1,000 Player Minecraf... by pjc50 on Tuesday June 27, 2023 @06:47AM (#36491185)
> not a criticism of Minecraft by the way, it's better to be popular and inefficient than not exist

I'm glad you said that, it's a very wise statement. It's the origin story of so many working-but-inefficient projects. We just don't see the graveyard of perfect-but-never-finished projects on the other side of the scale.