Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1074 thank(s) in 852 post(s)
To be more specific about why 18k hook calls is such a big number - that translates to 360k calls per second, and each such call needs to lock a CS for the plugin. Now imagine there are two worlds (normal and nether), each calling this hook, on a single-core machine. You get a whopping 360k context switches per second, this is normally impossible, current CPUs can handle some 20k context switches per second.
(wanted to post this immediately afterwards, but the forum died)
Posts: 1,450
Threads: 53
Joined: Feb 2011
Thanks: 15
Given 120 thank(s) in 91 post(s)
(11-22-2013, 07:18 AM)xoft Wrote: I fear that such a hook would seriously affect the server performance - it would be called several thousand times per tick (there are about 50 ticked blocks per loaded chunk per tick; a player normally loads 19*19 chunks -> 18k hook calls per player). We might have to accept that *some* kinds of plugins are just unreachable with current architecture.
Perhaps it's possible when calling a hook just once and supply a list of ticked blocks. This could require storing the ticked blocks. I'm not sure how much performance that costs but since there's a fixed amount of block ticks each server tick it could be stored in a fixed size array which should be pretty fast.
If you want to make mossy cobblestone grow I don't think this is the appropriate way to do it though, Lua is simply too slow to handle 18k block checks per tick. A more suitable way without needing the random tick hook would be inspecting each loaded chunk once and storing each (potentially growable) mossy cobblestone block after which the plugin manually selects a random stored block each tick to grow.
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1074 thank(s) in 852 post(s)
(11-22-2013, 08:14 AM)FakeTruth Wrote: ... it could be stored in a fixed size array which should be pretty fast. That's fast in C++, but giving that list to Lua means creating a Lua table, which means allocating lots of memory chunks off the heap, which is gonna be slow again. And it's not gonna bring the counts that low - 19*19 chunks, 20 times per second, is 7k calls per second, which means 14k thread context switches per second. Barely doable.
Remembering all the blocks eligible for growing is probably going to be too memory-intensive. There's nothing preventing the player from having an entire chunk full of mossy cobble, which would translate to storing 65k coord triplets. Again, too many heap allocations for storing that in a Lua table.
Might just be best to select a random few coords per chunk in each tick, see if there's a mossy cobble there and growing it then. Pity that the plugins don't have access to per-chunk ticking which would make it considerably faster; also there's no way to enumerate the loaded chunks, so probably this is not possible atm.
Posts: 1,450
Threads: 53
Joined: Feb 2011
Thanks: 15
Given 120 thank(s) in 91 post(s)
(11-22-2013, 03:51 PM)xoft Wrote: (11-22-2013, 08:14 AM)FakeTruth Wrote: ... it could be stored in a fixed size array which should be pretty fast. That's fast in C++, but giving that list to Lua means creating a Lua table, which means allocating lots of memory chunks off the heap, which is gonna be slow again. And it's not gonna bring the counts that low - 19*19 chunks, 20 times per second, is 7k calls per second, which means 14k thread context switches per second. Barely doable. You could wrap it with a C++ struct/class so it doesn't require a table in Lua.
(11-22-2013, 03:51 PM)xoft Wrote: Remembering all the blocks eligible for growing is probably going to be too memory-intensive. There's nothing preventing the player from having an entire chunk full of mossy cobble, which would translate to storing 65k coord triplets. Again, too many heap allocations for storing that in a Lua table.
Might just be best to select a random few coords per chunk in each tick, see if there's a mossy cobble there and growing it then. Pity that the plugins don't have access to per-chunk ticking which would make it considerably faster; also there's no way to enumerate the loaded chunks, so probably this is not possible atm. Like I said, only store potentially growable blocks. If you have an entire chunk full of mossy cobblestone blocks there is nothing left to grow there, it will store 0 blocks of that chunk.
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1074 thank(s) in 852 post(s)
A C++ class or struct would require an API and calling a function is a costly operation in this context - there's a function name lookup (stringmap), parameter serialization and deserialization... too heavy to be done on the order of 10k times per second.
Remembering only eligible blocks is problematic, too:
1. You need to classify them as soon as a chunk is loaded (how about chunk borders?). Costly.
2. There's still not much saved - if half of the blocks are mossy and the other half cobble, there's still 32k potentially growable blocks to remember.
Posts: 952
Threads: 16
Joined: May 2013
Thanks: 66
Given 105 thank(s) in 89 post(s)
Or, a plugin author could simply submit a PR for growing moss. Then, we could list it as a 'feature', making us look better than Vanilla.
Posts: 4,628
Threads: 115
Joined: Dec 2011
Thanks: 693
Given 494 thank(s) in 423 post(s)
I don't think that's smart. Imagine someone build a castle made out of cobble and he is using mossy cobble as decoration. Eventualy his whole castle would become out of mossy cobblestone. I think if someone wants mossy cobble to grow then he/she has to use a plugin and not something build in.
Posts: 1,450
Threads: 53
Joined: Feb 2011
Thanks: 15
Given 120 thank(s) in 91 post(s)
11-23-2013, 06:51 AM
(This post was last modified: 11-23-2013, 06:53 AM by FakeTruth.)
(11-22-2013, 09:54 PM)xoft Wrote: 2. There's still not much saved - if half of the blocks are mossy and the other half cobble, there's still 32k potentially growable blocks to remember.
Nah, I mean do it the same way Minecraft optimizes the use of triangles in rendering the chunks, only make triangles for the blocks that can potentially be visible, this means the border between outside and inside of the terrain.
Just store the moss blocks that are actually capable of growing to other blocks around them.
Code: ▢ = cobble
▣ = mossy
▢▢▢▢▢▢▢
▢▢▣▣▣▢▢
▢▣▣▣▣▣▢
▢▣▣▣▣▣▢
▢▣▣▣▣▣▢
▢▢▢▢▢▢▢
Then you would only store these blocks because the blocks in the center cannot grow more.
Code: ▢ = ignored
▣ = stored
▢▢▢▢▢▢▢
▢▢▣▣▣▢▢
▢▣▢▢▢▣▢
▢▣▢▢▢▣▢
▢▣▣▣▣▣▢
▢▢▢▢▢▢▢
Now I don't know how many mossy cobblestone blocks actually exist in a chunk normally and the way it should grow. You could also limit the growth of mossy blocks to only blocks that are exposed to air. That should greatly limit the number of blocks you need to store.
Posts: 952
Threads: 16
Joined: May 2013
Thanks: 66
Given 105 thank(s) in 89 post(s)
(11-23-2013, 06:44 AM)STR_Warrior Wrote: I don't think that's smart. Imagine someone build a castle made out of cobble and he is using mossy cobble as decoration. Eventualy his whole castle would become out of mossy cobblestone. I think if someone wants mossy cobble to grow then he/she has to use a plugin and not something build in.
Light level check, air check, and possibly water check. Problem solved
Posts: 4,628
Threads: 115
Joined: Dec 2011
Thanks: 693
Given 494 thank(s) in 423 post(s)
11-23-2013, 07:17 AM
(This post was last modified: 05-18-2015, 05:15 PM by NiLSPACE.)
But still. Massive cobblestone structure with one mossy cobblestone nearby and boom structure ruined. I think stuff like this should be done by plugins and not by the server itself.
|