diff options
author | RĂ©mi Verschelde <remi@verschelde.fr> | 2021-11-08 13:39:39 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-08 13:39:39 +0100 |
commit | e87687a6d0bd052d282b0645b7fff47c5559c981 (patch) | |
tree | 088dfb41f984caefac2031eeec86d0d05fcd3523 | |
parent | 63559f2c80e29231596aec9cee4de79139584373 (diff) | |
parent | 151d2e34caff77b9b2ffcadea1e4fa0a7ddd450c (diff) |
Merge pull request #54486 from ibrahn/thread-work-pool-lazier
-rw-r--r-- | core/templates/thread_work_pool.h | 24 | ||||
-rw-r--r-- | servers/physics_2d/godot_step_2d.cpp | 6 | ||||
-rw-r--r-- | servers/physics_3d/godot_step_3d.cpp | 6 |
3 files changed, 22 insertions, 14 deletions
diff --git a/core/templates/thread_work_pool.h b/core/templates/thread_work_pool.h index b242648bc8..19096c496a 100644 --- a/core/templates/thread_work_pool.h +++ b/core/templates/thread_work_pool.h @@ -73,6 +73,7 @@ class ThreadWorkPool { ThreadData *threads = nullptr; uint32_t thread_count = 0; + uint32_t threads_working = 0; BaseWork *current_work = nullptr; static void _thread_function(void *p_user); @@ -94,7 +95,9 @@ public: current_work = w; - for (uint32_t i = 0; i < thread_count; i++) { + threads_working = MIN(p_elements, thread_count); + + for (uint32_t i = 0; i < threads_working; i++) { threads[i].work = w; threads[i].start.post(); } @@ -117,19 +120,32 @@ public: void end_work() { ERR_FAIL_COND(current_work == nullptr); - for (uint32_t i = 0; i < thread_count; i++) { + for (uint32_t i = 0; i < threads_working; i++) { threads[i].completed.wait(); threads[i].work = nullptr; } + threads_working = 0; memdelete(current_work); current_work = nullptr; } template <class C, class M, class U> void do_work(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) { - begin_work(p_elements, p_instance, p_method, p_userdata); - end_work(); + switch (p_elements) { + case 0: + // Nothing to do, so do nothing. + break; + case 1: + // No value in pushing the work to another thread if it's a single job + // and we're going to wait for it to finish. Just run it right here. + (p_instance->*p_method)(0, p_userdata); + break; + default: + // Multiple jobs to do; commence threaded business. + begin_work(p_elements, p_instance, p_method, p_userdata); + end_work(); + } } _FORCE_INLINE_ int get_thread_count() const { return thread_count; } diff --git a/servers/physics_2d/godot_step_2d.cpp b/servers/physics_2d/godot_step_2d.cpp index 3010315571..84ec0e3c63 100644 --- a/servers/physics_2d/godot_step_2d.cpp +++ b/servers/physics_2d/godot_step_2d.cpp @@ -255,11 +255,7 @@ void GodotStep2D::step(GodotSpace2D *p_space, real_t p_delta, int p_iterations) // Warning: _solve_island modifies the constraint islands for optimization purpose, // their content is not reliable after these calls and shouldn't be used anymore. - if (island_count > 1) { - work_pool.do_work(island_count, this, &GodotStep2D::_solve_island, nullptr); - } else if (island_count > 0) { - _solve_island(0); - } + work_pool.do_work(island_count, this, &GodotStep2D::_solve_island, nullptr); { //profile profile_endtime = OS::get_singleton()->get_ticks_usec(); diff --git a/servers/physics_3d/godot_step_3d.cpp b/servers/physics_3d/godot_step_3d.cpp index a8654c617b..331d65df49 100644 --- a/servers/physics_3d/godot_step_3d.cpp +++ b/servers/physics_3d/godot_step_3d.cpp @@ -359,11 +359,7 @@ void GodotStep3D::step(GodotSpace3D *p_space, real_t p_delta, int p_iterations) // Warning: _solve_island modifies the constraint islands for optimization purpose, // their content is not reliable after these calls and shouldn't be used anymore. - if (island_count > 1) { - work_pool.do_work(island_count, this, &GodotStep3D::_solve_island, nullptr); - } else if (island_count > 0) { - _solve_island(0); - } + work_pool.do_work(island_count, this, &GodotStep3D::_solve_island, nullptr); { //profile profile_endtime = OS::get_singleton()->get_ticks_usec(); |