ABM Optimization

Post Reply
Odracir
Member
Posts: 21
Joined: Thu Sep 19, 2019 00:55

ABM Optimization

by Odracir » Post

If Im not wrong, ABMs run roughly this way...

Code: Select all

Stage
  1   Every 'abm_interval' (minetest.conf) seconds: 
  2     For each registered ABM:   
        ( Oh, what a nice mod, I want it.And this too, and this ... -> more, moore, mooore ABMs )
  3       For each active mapblock:    ( 27 , or 125 ? per player)
  4         If 'catch_up' = true , evaluate 'chance' reduction
  5           For z = min -> max (northwards)
  6             For y = min -> max (upwards)
  7               For x = min -> max (eastwards)
                    ... following is done 16*16*16 = 4096 times per active mapblock ...
                    ... if  27 active mapblocks per player, [color=#FF0000]110592 times per player[/color]
                    ... if 125 active mapblocks per player,[color=#FF0000] 512000 times per player 
                    .... ( half a million ! )[/color]
  8                 If node(x,y,z) belongs to 'nodenames'
  9                   If any of its 26 neighbors belong to 'neighbors'
 10                     If ...'chance' & RNG then call our callback
 11                       func(pos, node, active_object_count, active_object_count_wider)
 12                         [If <condition X> then]   [b] <condition X>[/b] could be none
 13                           [b]<do whatever>[/b]


Most of it is silent, hidden, highly efficient C++, but an enormous work.
And for some uses, the goal, <do whatever>, depends on some <condition X>
All is OK if <condition X> needs to be evaluated per-node.

But if <condition X> is met more widely, there is a HUGE waste of CPU.

Examples:

- Some mod has a good reason to temporarily suspend one of its ABMs
- Turn leaves brown if season == 'autumn'
- Spawn mob if z > 0 (a world with safe south and risky north)
- Spawn photophobic monster if time of day == night
- Do something if y < -20 (if underground)
- Do something not extremely accurate depending on biome/humidity/temperature
(things that vary smoothly, roughly equal through a mapblock)

Performance would greatly improve allowing extra conditions to prune the ABM tasks in earlier stages, for example:

- In stage 2 - each ABM could have a boolean 'active' flag, mods could suspend and resume.
- Between stages 2 and 3 - <ABM global condition> (things like season, time of day...)
- Between stages 3 and 4 - <ABM mapblock condition> (things like pos, biome, heat, humidity...)

<ABM global condition> and <ABM mapblock condition> could be easily added as optional arguments:

Code: Select all

    minetest.register_abm({
        label = "...",
        nodenames = {...},
        neighbors = {...},
        interval = ...,
        chance = ...,
        action = function(pos, node)...end,
        global_condition = function()...end,       --OPTIONAL
        mapblock_condition = function(pos)...end   --OPTIONAL
    })
Current mods would work without problem, nothing is broken. No painful forced rewrites.

And perhaps (requires ABM labels to be unique).Or using ABM index returned at registration

Code: Select all

  minetest.pause_abm( ABM_label )
  minetest.resume_abm( ABM_label )
Many mods could take advantage of this. Weather, seasons, biomes, mobs ...

User avatar
texmex
Member
Posts: 1752
Joined: Mon Jul 11, 2016 21:08
GitHub: tacotexmex
In-game: tacotexmex

Re: ABM Optimization

by texmex » Post

Agreed, this would be quite useful.
Mods | Support Mesehub: bc1qluuests9rxmlnvpjrhsnyjg9ucwy6z3r0y3srw

ShadMOrdre
Member
Posts: 775
Joined: Mon Dec 29, 2014 08:07
GitHub: ShadMOrdre
In-game: shadmordre
Location: USA

Re: ABM Optimization

by ShadMOrdre » Post

The Adventuretest game uses an interesting mechanism.

All mods register global_step, abms, and on_generated calls through a single wrapper.

ABMs, and the boolean test, are probably better handled outside the ABM, otherwise the ABM still has to run to test for whether it is enabled or not. This does need some TLC.

The on_generated wrapper provides a Lua efficient vm or voxelmanip, that each mod.on_generated function hooks into. This is already done, to a small degree, in the Adventuretest game.

The same is true for global_step, each much hooks into a single global_step call. Also done, in Adventuretest.
MY MODS: lib_ecology lib_materials lib_clouds lib_node_shapes ---- Inspired By: Open Source Virtual World Simulator Opensimulator.

Xudo
Member
Posts: 162
Joined: Wed Nov 09, 2016 16:43
GitHub: akryukov92
In-game: Xudo

Re: ABM Optimization

by Xudo » Post

I'm sure it is possible to use some math trick, which allow to avoid iterating over x,y,z. Though I don't have required knowledge to implement it.

User avatar
Pyrollo
Developer
Posts: 385
Joined: Mon Jan 08, 2018 15:14
GitHub: pyrollo
In-game: Naj
Location: Paris

Re: ABM Optimization

by Pyrollo » Post

Xudo wrote:I'm sure it is possible to use some math trick, which allow to avoid iterating over x,y,z. Though I don't have required knowledge to implement it.
On a database point of view, indexing avoids full scans.

On loading each map block, and ABM index could be build, and maintained on each map block modification.

This index could be per ABM (easier to switch on/off at map block level). When firing ABM, iterating through index.

If there are not too many blocks with ABM this could save time, but consumes more memory.
[ Display Modpack ] - [ Digiterms ] - [ Crater MG ] - [ LATE ]

Xudo
Member
Posts: 162
Joined: Wed Nov 09, 2016 16:43
GitHub: akryukov92
In-game: Xudo

Re: ABM Optimization

by Xudo » Post

I meant special implementation of random function, which will choose specific block with defined chance.

Odracir
Member
Posts: 21
Joined: Thu Sep 19, 2019 00:55

Re: ABM Optimization

by Odracir » Post

Found another thread worth reading [Discussion] Mods performance improvements.

Explains /profiler command and its settings in minetest.conf, and more.

This seems to be different from F6 key profiling, and gives data per mod.

Astrobe
Member
Posts: 329
Joined: Sun Apr 01, 2018 10:46

Re: ABM Optimization

by Astrobe » Post

I think adding a ymin an ymax property (min/max altitude) should also be considered. When applicable this is a win-win: the engine can skip iterations, and the ABM callback doesn't have to perform that check. The real question is how often it is applicable, though.

User avatar
Festus1965
Member
Posts: 1783
Joined: Sun Jan 03, 2016 11:58
In-game: Thomas Thailand Explorer
Location: Thailand ChiangMai
Contact:

Re: ABM Optimization

by Festus1965 » Post

I had another idea last weeks and tested it a bit:

Base now is ABM run from server every 1 sec and many mods with every sec and some change 1 sec, as also.

I changed in source that ABM run every 0.1 sec combined with setting in .conf,
and set the most hard ABM using mod (technic, pipeworks and mesecons) to different repeating:
* technic every 0.7,
* pipeworks every 0.8
* mesecons every 0.9
* rest keep on standard as set in mod

= NOW not all mod ABM repeat same time at every 1 sec, now they are separated, spread over a sec and meet also less time all on the same sec (accumulating a lot time).

That reduced the warnings on needed too long a lot and so far I didn't find problems yet.

But further tests have to run about this, but it would be better to think first about this idea what is causes beside.
Human has no future (climate change)
If urgend, you find me in Roblox (as CNXThomas)

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests