Merge pull request #54486 from ibrahn/thread-work-pool-lazier
This commit is contained in:
commit
e87687a6d0
|
@ -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; }
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue