summaryrefslogtreecommitdiff
path: root/src/serverenvironment.cpp
diff options
context:
space:
mode:
authorLars Hofhansl <larsh@apache.org>2019-07-07 23:23:00 -0700
committerLars Hofhansl <larsh@apache.org>2019-07-07 23:23:00 -0700
commit0971a14a57c373330b04d355689553f6ddfa6bcb (patch)
tree4cffac872c9a3456c30b9d988b90cdf6e75da9c1 /src/serverenvironment.cpp
parent3a8ac9b03199cf0773107e58c69dd078892284a2 (diff)
downloadminetest-0971a14a57c373330b04d355689553f6ddfa6bcb.tar.gz
minetest-0971a14a57c373330b04d355689553f6ddfa6bcb.tar.bz2
minetest-0971a14a57c373330b04d355689553f6ddfa6bcb.zip
Improve ABM time budget handling. #8645
Diffstat (limited to 'src/serverenvironment.cpp')
-rw-r--r--src/serverenvironment.cpp87
1 files changed, 50 insertions, 37 deletions
diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp
index 0a83c4a38..3c4733130 100644
--- a/src/serverenvironment.cpp
+++ b/src/serverenvironment.cpp
@@ -384,6 +384,9 @@ void ActiveBlockList::update(std::vector<PlayerSAO*> &active_players,
ServerEnvironment
*/
+// Random device to seed pseudo random generators.
+static std::random_device seed;
+
ServerEnvironment::ServerEnvironment(ServerMap *map,
ServerScripting *scriptIface, Server *server,
const std::string &path_world):
@@ -391,7 +394,8 @@ ServerEnvironment::ServerEnvironment(ServerMap *map,
m_map(map),
m_script(scriptIface),
m_server(server),
- m_path_world(path_world)
+ m_path_world(path_world),
+ m_rgen(seed())
{
// Determine which database backend to use
std::string conf_path = path_world + DIR_DELIM + "world.mt";
@@ -1338,47 +1342,56 @@ void ServerEnvironment::step(float dtime)
}
}
- if (m_active_block_modifier_interval.step(dtime, m_cache_abm_interval))
- do { // breakable
- if (m_active_block_interval_overload_skip > 0) {
- ScopeProfiler sp(g_profiler, "SEnv: ABM overload skips");
- m_active_block_interval_overload_skip--;
- break;
- }
- ScopeProfiler sp(g_profiler, "SEnv: modify in blocks avg per interval", SPT_AVG);
- TimeTaker timer("modify in active blocks per interval");
-
- // Initialize handling of ActiveBlockModifiers
- ABMHandler abmhandler(m_abms, m_cache_abm_interval, this, true);
-
- int blocks_scanned = 0;
- int abms_run = 0;
- int blocks_cached = 0;
- for (const v3s16 &p : m_active_blocks.m_abm_list) {
- MapBlock *block = m_map->getBlockNoCreateNoEx(p);
- if (!block)
- continue;
+ if (m_active_block_modifier_interval.step(dtime, m_cache_abm_interval)) {
+ ScopeProfiler sp(g_profiler, "SEnv: modify in blocks avg per interval", SPT_AVG);
+ TimeTaker timer("modify in active blocks per interval");
- // Set current time as timestamp
- block->setTimestampNoChangedFlag(m_game_time);
+ // Initialize handling of ActiveBlockModifiers
+ ABMHandler abmhandler(m_abms, m_cache_abm_interval, this, true);
- /* Handle ActiveBlockModifiers */
- abmhandler.apply(block, blocks_scanned, abms_run, blocks_cached);
- }
- g_profiler->avg("SEnv: active blocks", m_active_blocks.m_abm_list.size());
- g_profiler->avg("SEnv: active blocks cached", blocks_cached);
- g_profiler->avg("SEnv: active blocks scanned for ABMs", blocks_scanned);
- g_profiler->avg("SEnv: ABMs run", abms_run);
+ int blocks_scanned = 0;
+ int abms_run = 0;
+ int blocks_cached = 0;
+
+ std::vector<v3s16> output(m_active_blocks.m_abm_list.size());
+
+ // Shuffle the active blocks so that each block gets an equal chance
+ // of having its ABMs run.
+ std::copy(m_active_blocks.m_abm_list.begin(), m_active_blocks.m_abm_list.end(), output.begin());
+ std::shuffle(output.begin(), output.end(), m_rgen);
+
+ int i = 0;
+ // The time budget for ABMs is 20%.
+ u32 max_time_ms = m_cache_abm_interval * 1000 / 5;
+ for (const v3s16 &p : output) {
+ MapBlock *block = m_map->getBlockNoCreateNoEx(p);
+ if (!block)
+ continue;
+
+ i++;
+
+ // Set current time as timestamp
+ block->setTimestampNoChangedFlag(m_game_time);
+
+ /* Handle ActiveBlockModifiers */
+ abmhandler.apply(block, blocks_scanned, abms_run, blocks_cached);
+
+ u32 time_ms = timer.getTimerTime();
- u32 time_ms = timer.stop(true);
- u32 max_time_ms = 200;
if (time_ms > max_time_ms) {
- warningstream<<"active block modifiers took "
- <<time_ms<<"ms (longer than "
- <<max_time_ms<<"ms)"<<std::endl;
- m_active_block_interval_overload_skip = (time_ms / max_time_ms) + 1;
+ warningstream << "active block modifiers took "
+ << time_ms << "ms (processed " << i << " of "
+ << output.size() << " active blocks)" << std::endl;
+ break;
}
- }while(0);
+ }
+ g_profiler->avg("SEnv: active blocks", m_active_blocks.m_abm_list.size());
+ g_profiler->avg("SEnv: active blocks cached", blocks_cached);
+ g_profiler->avg("SEnv: active blocks scanned for ABMs", blocks_scanned);
+ g_profiler->avg("SEnv: ABMs run", abms_run);
+
+ timer.stop(true);
+ }
/*
Step script environment (run global on_step())