From b3f650fba30a92596a57ec84b71ca273531159d1 Mon Sep 17 00:00:00 2001 From: Mikulas Florek Date: Fri, 22 Nov 2024 01:02:36 +0100 Subject: [PATCH] optimization - parallel module update --- src/animation/animation_module.cpp | 16 ++++++++++------ src/engine/engine.cpp | 8 ++++++-- src/engine/plugin.h | 6 ++++++ src/lua/lua_script_system.cpp | 2 +- src/navigation/navigation_module.cpp | 16 ++++++++++------ src/physics/physics_module.cpp | 8 ++++++-- src/renderer/render_module.cpp | 1 + 7 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/animation/animation_module.cpp b/src/animation/animation_module.cpp index d93ed97b2c..82d87bc6ac 100644 --- a/src/animation/animation_module.cpp +++ b/src/animation/animation_module.cpp @@ -755,19 +755,23 @@ struct AnimationModuleImpl final : AnimationModule { } - void update(float time_delta) override - { + void updateParallel(float time_delta) override { PROFILE_FUNCTION(); if (!m_is_game_running) return; - - updateAnimables(time_delta); - updatePropertyAnimators(time_delta); - + jobs::forEach(m_animators.size(), 1, [&](i32 idx, i32){ updateAnimator(m_animators[idx], time_delta); }); } + void update(float time_delta) override { + PROFILE_FUNCTION(); + if (!m_is_game_running) return; + + updateAnimables(time_delta); + updatePropertyAnimators(time_delta); + } + PropertyAnimation* loadPropertyAnimation(const Path& path) const { diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index d4804c7ec8..6b7c3db11c 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -309,16 +309,20 @@ struct EngineImpl final : Engine { computeSmoothTimeDelta(); if (!m_paused || m_next_frame) { + auto& modules = world.getModules(); + jobs::forEach(modules.size(), 1, [&](u32 idx, u32){ + modules[idx]->updateParallel(dt); + }); { PROFILE_BLOCK("update modules"); - for (UniquePtr& module : world.getModules()) + for (UniquePtr& module : modules) { module->update(dt); } } { PROFILE_BLOCK("late update modules"); - for (UniquePtr& module : world.getModules()) + for (UniquePtr& module : modules) { module->lateUpdate(dt); } diff --git a/src/engine/plugin.h b/src/engine/plugin.h index 5d185b24f8..68cee9673e 100644 --- a/src/engine/plugin.h +++ b/src/engine/plugin.h @@ -45,8 +45,14 @@ struct LUMIX_ENGINE_API IModule virtual void afterReload(InputMemoryStream& serializer) {} virtual const char* getName() const = 0; virtual ISystem& getSystem() const = 0; + + // called for all modules at once, i.e. all modules are updated in parallel + virtual void updateParallel(float time_delta) {} + // called after all updateParallel calls are finished, called on "main thread" virtual void update(float time_delta) = 0; + // called after all update calls are finished, called on "main thread" virtual void lateUpdate(float time_delta) {} + virtual void endFrame() {} virtual struct World& getWorld() = 0; virtual void startGame() {} diff --git a/src/lua/lua_script_system.cpp b/src/lua/lua_script_system.cpp index db67859d01..476417228b 100644 --- a/src/lua/lua_script_system.cpp +++ b/src/lua/lua_script_system.cpp @@ -2961,7 +2961,7 @@ void LuaScriptModuleImpl::ScriptInstance::onScriptLoaded(LuaScriptModuleImpl& mo lua_pop(m_state, 1); // [] } - module.m_to_start.push({cmp.m_entity, (u32)scr_index, false, module.m_is_game_running}); + module.m_to_start.push({cmp.m_entity, (u32)scr_index, false, is_reload && module.m_is_game_running}); } diff --git a/src/navigation/navigation_module.cpp b/src/navigation/navigation_module.cpp index 045b9d4ea9..9b4a879503 100644 --- a/src/navigation/navigation_module.cpp +++ b/src/navigation/navigation_module.cpp @@ -363,12 +363,6 @@ struct NavigationModuleImpl final : NavigationModule void update(RecastZone& zone, float time_delta) { - if (!zone.crowd) return; - { - PROFILE_BLOCK("dtCrowd::update"); - zone.crowd->update(time_delta, nullptr); - } - for (auto& agent : m_agents) { if (agent.agent < 0) continue; if (agent.zone != zone.entity) continue; @@ -398,6 +392,16 @@ struct NavigationModuleImpl final : NavigationModule } } + void updateParallel(float time_delta) override { + if (!m_is_game_running) return; + + for (RecastZone& zone : m_zones) { + if (!zone.crowd) continue; + PROFILE_BLOCK("dtCrowd::update"); + zone.crowd->update(time_delta, nullptr); + } + } + void lateUpdate(RecastZone& zone, float time_delta) { if (!zone.crowd) return; diff --git a/src/physics/physics_module.cpp b/src/physics/physics_module.cpp index 255f4461ba..b560258093 100644 --- a/src/physics/physics_module.cpp +++ b/src/physics/physics_module.cpp @@ -1836,14 +1836,18 @@ struct PhysicsModuleImpl final : PhysicsModule updateDynamicActors(false); } - void update(float time_delta) override - { + void updateParallel(float time_delta) override { if (!m_is_game_running) return; time_delta = minimum(1 / 20.0f, time_delta); updateVehicles(time_delta); simulateScene(time_delta); fetchResults(); + } + + void update(float time_delta) override { + if (!m_is_game_running) return; + updateDynamicActors(true); updateControllers(time_delta); diff --git a/src/renderer/render_module.cpp b/src/renderer/render_module.cpp index b97fccff00..d04aa76e59 100644 --- a/src/renderer/render_module.cpp +++ b/src/renderer/render_module.cpp @@ -528,6 +528,7 @@ struct RenderModuleImpl final : RenderModule { StackArray to_delete(m_allocator); jobs::Mutex mutex; ParticleSystem::Stats stats = {}; + // TODO move to parallel update? jobs::forEach(m_particle_emitters.capacity(), 1, [&](i32 idx, i32){ ParticleSystem* ps = m_particle_emitters.getFromIndex(idx); if (!ps) return;