5#include "Services/TaskManager.h"
6#include "Platform/Instrumentation.h"
8#include "Foundation/ComponentModel/Component.h"
9#include "Foundation/Platform/Threads.h"
17 template<
typename Pool,
typename Func>
18 void processComponents(Pool & pool, Func func)
21 for (
auto & component : pool) {
34 void Wait() { taskManager->
wait(group); }
40 template<
typename Func>
41 TaskScope forEach(
Context * context,
size_t count, Func f,
const char * scopeTag =
"")
44 const size_t hwc = context->
taskManager->getQueueConcurrency(queue);
45 if (count <= 1 || hwc < 1) {
47 DynamicCpuInstrumentationScope(SCOPE_PARALLEL,
"forEach", scopeTag);
48 for (
size_t j = 0; j < count; ++j) {
52 return TaskScope{ context->
taskManager.get(), NoTask };
55 const size_t perTask = (count / hwc) + 1;
57 auto group = context->
taskManager->createGroup(queue);
59 for (
size_t i = 0; i < hwc; ++i) {
60 const size_t begin = i * perTask;
61 const size_t end = std::min(begin + perTask, count);
63 if (begin >= count)
continue;
67 DynamicCpuInstrumentationScope(SCOPE_PARALLEL,
"forEach", scopeTag);
69 for (
size_t j = begin; j < end; ++j) {
75 return TaskScope{ context->
taskManager.get(), group };
78 template<
typename Func>
79 TaskScope forEachRanged(Context* context,
size_t count, Func f,
size_t minSize = 0,
const char* scopeTag =
"")
82 const size_t hwc = context->taskManager->getQueueConcurrency(queue);
83 if (count < minSize || hwc < 1) {
85 DynamicCpuInstrumentationScope(SCOPE_PARALLEL,
"forEachRanged", scopeTag);
88 return TaskScope{ context->taskManager.get(), NoTask };
90 const size_t perTask = std::max(minSize, (count / hwc) + 1);
92 TaskId group = context->taskManager->createGroup(queue);
94 for (
size_t i = 0; i < hwc; ++i) {
95 const size_t begin = i * perTask;
96 const size_t end = std::min(begin + perTask, count);
98 if (begin >= count)
continue;
100 context->taskManager->enqueueChild(group, [=]()
102 DynamicCpuInstrumentationScope(SCOPE_PARALLEL,
"forEachRanged", scopeTag);
107 return TaskScope{ context->taskManager.get(), group };
110 template<
typename Pool,
typename Func>
111 TaskId processComponents(Context * context, Pool & pool,
const char * scopeName, Func func, TaskId taskGroup = NoTask)
113 const size_t numComponents = pool.size();
115 const size_t hwc = context->taskManager->getQueueConcurrency(queue);
116 if (numComponents <= 1 || hwc < 1) {
118 DynamicCpuInstrumentationScope(SCOPE_PARALLEL,
"processComponents", scopeName);
119 for (
size_t j = 0; j < numComponents; j++) {
120 func(pool[
static_cast<SizeType>(j)], j);
126 if (!taskGroup.isValid()) {
127 taskGroup = context->taskManager->createGroup(queue);
129 const size_t perTask = (numComponents / hwc) + 1;
130 for (
size_t i = 0; i < hwc; ++i) {
131 const size_t begin = i * perTask;
132 const size_t end = std::min(begin + perTask, numComponents);
134 if (begin >= numComponents)
continue;
136 context->taskManager->enqueueChild(taskGroup, [&pool, scopeName, func, begin, end]()
138 DynamicCpuInstrumentationScope(SCOPE_PARALLEL,
"processComponents", scopeName);
139 for (
size_t j = begin; j < end; ++j) {
140 func(pool[
static_cast<SizeType>(j)], j);
147 template<
typename Pool,
typename Func>
148 TaskId processComponents(Context * context, Pool & pool, Func func, TaskId taskGroup = NoTask)
150 return processComponents(context, pool,
"Parallel::processComponents", func, taskGroup);
A Context instance contains all the services, systems and runtime components needed to use Cogs.
std::unique_ptr< class TaskManager > taskManager
TaskManager service instance.
Manages Task queuing and execution.
void wait(const TaskId &taskId)
Wait for the task given by taskId.
static constexpr TaskQueueId GlobalQueue
Global task queue.
void destroy(const TaskId &taskId)
Destroy the task given by taskId.
uint16_t TaskQueueId
Unique id for a task queue.
Contains all Cogs related functionality.
ComponentIndex SizeType
Type used to track the size of pools.
Task id struct used to identify unique Task instances.
bool isValid() const
Check if the task id is valid.