mirror of
https://github.com/godotengine/godot.git
synced 2024-11-21 03:18:37 +08:00
WorkerThreadPool: Avoid most runtime allocations
Just a little optimization. **NOTE:** With `RID_Owner` we could replace each pair of `PagedAllocator` and `HashMap`-of-ids-to-pointers. However, that would force us to expose `RID` as the task/group id, instead of `int`, which would break the API. Too bad. Let's wait until Godot 5.0.
This commit is contained in:
parent
ae418f9469
commit
a731774813
@ -613,13 +613,14 @@ void WorkerThreadPool::finish() {
|
||||
return;
|
||||
}
|
||||
|
||||
task_mutex.lock();
|
||||
SelfList<Task> *E = low_priority_task_queue.first();
|
||||
while (E) {
|
||||
print_error("Task waiting was never re-claimed: " + E->self()->description);
|
||||
E = E->next();
|
||||
{
|
||||
MutexLock lock(task_mutex);
|
||||
SelfList<Task> *E = low_priority_task_queue.first();
|
||||
while (E) {
|
||||
print_error("Task waiting was never re-claimed: " + E->self()->description);
|
||||
E = E->next();
|
||||
}
|
||||
}
|
||||
task_mutex.unlock();
|
||||
|
||||
{
|
||||
MutexLock lock(task_mutex);
|
||||
@ -632,6 +633,13 @@ void WorkerThreadPool::finish() {
|
||||
data.thread.wait_to_finish();
|
||||
}
|
||||
|
||||
{
|
||||
MutexLock lock(task_mutex);
|
||||
for (KeyValue<TaskID, Task *> &E : tasks) {
|
||||
task_allocator.free(E.value);
|
||||
}
|
||||
}
|
||||
|
||||
threads.clear();
|
||||
}
|
||||
|
||||
|
@ -95,8 +95,11 @@ private:
|
||||
task_elem(this) {}
|
||||
};
|
||||
|
||||
PagedAllocator<Task> task_allocator;
|
||||
PagedAllocator<Group> group_allocator;
|
||||
static const uint32_t TASKS_PAGE_SIZE = 1024;
|
||||
static const uint32_t GROUPS_PAGE_SIZE = 256;
|
||||
|
||||
PagedAllocator<Task, false, TASKS_PAGE_SIZE> task_allocator;
|
||||
PagedAllocator<Group, false, GROUPS_PAGE_SIZE> group_allocator;
|
||||
|
||||
SelfList<Task>::List low_priority_task_queue;
|
||||
SelfList<Task>::List task_queue;
|
||||
@ -117,8 +120,20 @@ private:
|
||||
bool exit_threads = false;
|
||||
|
||||
HashMap<Thread::ID, int> thread_ids;
|
||||
HashMap<TaskID, Task *> tasks;
|
||||
HashMap<GroupID, Group *> groups;
|
||||
HashMap<
|
||||
TaskID,
|
||||
Task *,
|
||||
HashMapHasherDefault,
|
||||
HashMapComparatorDefault<TaskID>,
|
||||
PagedAllocator<HashMapElement<TaskID, Task *>, false, TASKS_PAGE_SIZE>>
|
||||
tasks;
|
||||
HashMap<
|
||||
GroupID,
|
||||
Group *,
|
||||
HashMapHasherDefault,
|
||||
HashMapComparatorDefault<GroupID>,
|
||||
PagedAllocator<HashMapElement<GroupID, Group *>, false, GROUPS_PAGE_SIZE>>
|
||||
groups;
|
||||
|
||||
uint32_t max_low_priority_threads = 0;
|
||||
uint32_t low_priority_threads_used = 0;
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
|
||||
template <class T, bool thread_safe = false>
|
||||
template <class T, bool thread_safe = false, uint32_t DEFAULT_PAGE_SIZE = 4096>
|
||||
class PagedAllocator {
|
||||
T **page_pool = nullptr;
|
||||
T ***available_pool = nullptr;
|
||||
@ -53,10 +53,6 @@ class PagedAllocator {
|
||||
SpinLock spin_lock;
|
||||
|
||||
public:
|
||||
enum {
|
||||
DEFAULT_PAGE_SIZE = 4096
|
||||
};
|
||||
|
||||
template <class... Args>
|
||||
T *alloc(Args &&...p_args) {
|
||||
if (thread_safe) {
|
||||
|
Loading…
Reference in New Issue
Block a user