Plasma Engine  2.0
Loading...
Searching...
No Matches
ParallelFor_inl.h
1#pragma once
2
3#include <Foundation/Memory/FrameAllocator.h>
4#include <Foundation/Profiling/Profiling.h>
5
6template <typename ElemType>
7class ArrayPtrTask final : public plTask
8{
9public:
10 ArrayPtrTask(plArrayPtr<ElemType> payload, plParallelForFunction<ElemType> taskCallback, plUInt32 uiItemsPerInvocation)
11 : m_Payload(payload)
12 , m_uiItemsPerInvocation(uiItemsPerInvocation)
13 , m_TaskCallback(std::move(taskCallback))
14 {
15 }
16
17 void Execute() override
18 {
19 // Work through all of them.
20 m_TaskCallback(0, m_Payload);
21 }
22
23 void ExecuteWithMultiplicity(plUInt32 uiInvocation) const override
24 {
25 const plUInt32 uiSliceStartIndex = uiInvocation * m_uiItemsPerInvocation;
26
27 const plUInt32 uiRemainingItems = uiSliceStartIndex > m_Payload.GetCount() ? 0 : m_Payload.GetCount() - uiSliceStartIndex;
28 const plUInt32 uiSliceItemCount = plMath::Min(m_uiItemsPerInvocation, uiRemainingItems);
29
30 if (uiSliceItemCount > 0)
31 {
32 // Run through the calculated slice.
33 auto taskItemSlice = m_Payload.GetSubArray(uiSliceStartIndex, uiSliceItemCount);
34 m_TaskCallback(uiSliceStartIndex, taskItemSlice);
35 }
36 }
37
38private:
39 plArrayPtr<ElemType> m_Payload;
40 plUInt32 m_uiItemsPerInvocation;
42};
43
44template <typename ElemType>
45void plTaskSystem::ParallelForInternal(plArrayPtr<ElemType> taskItems, plParallelForFunction<ElemType> taskCallback, const char* taskName, const plParallelForParams& params)
46{
47 if (taskItems.GetCount() <= params.m_uiBinSize)
48 {
49 ArrayPtrTask<ElemType> arrayPtrTask(taskItems, std::move(taskCallback), taskItems.GetCount());
50 arrayPtrTask.ConfigureTask(taskName ? taskName : "Generic ArrayPtr Task", params.m_NestingMode);
51
52 PL_PROFILE_SCOPE(arrayPtrTask.m_sTaskName);
53 arrayPtrTask.Execute();
54 }
55 else
56 {
57 plUInt32 uiMultiplicity;
58 plUInt64 uiItemsPerInvocation;
59 params.DetermineThreading(taskItems.GetCount(), uiMultiplicity, uiItemsPerInvocation);
60
61 plAllocator* pAllocator = (params.m_pTaskAllocator != nullptr) ? params.m_pTaskAllocator : plFoundation::GetDefaultAllocator();
62
63 plSharedPtr<ArrayPtrTask<ElemType>> pArrayPtrTask = PL_NEW(pAllocator, ArrayPtrTask<ElemType>, taskItems, std::move(taskCallback), static_cast<plUInt32>(uiItemsPerInvocation));
64 pArrayPtrTask->ConfigureTask(taskName ? taskName : "Generic ArrayPtr Task", params.m_NestingMode);
65
66 pArrayPtrTask->SetMultiplicity(uiMultiplicity);
68 plTaskSystem::WaitForGroup(taskGroupId);
69 }
70}
71
72template <typename ElemType, typename Callback>
73void plTaskSystem::ParallelFor(plArrayPtr<ElemType> taskItems, Callback taskCallback, const char* szTaskName, const plParallelForParams& params)
74{
75 auto wrappedCallback = [taskCallback = std::move(taskCallback)](
76 plUInt32 /*uiBaseIndex*/, plArrayPtr<ElemType> taskSlice)
77 { taskCallback(taskSlice); };
78
79 ParallelForInternal<ElemType>(
80 taskItems, plParallelForFunction<ElemType>(std::move(wrappedCallback), plFrameAllocator::GetCurrentAllocator()), szTaskName, params);
81}
82
83template <typename ElemType, typename Callback>
84void plTaskSystem::ParallelForSingle(plArrayPtr<ElemType> taskItems, Callback taskCallback, const char* szTaskName, const plParallelForParams& params)
85{
86 auto wrappedCallback = [taskCallback = std::move(taskCallback)](plUInt32 /*uiBaseIndex*/, plArrayPtr<ElemType> taskSlice)
87 {
88 // Handing in by non-const& allows to use callbacks with (non-)const& as well as value parameters.
89 for (ElemType& taskItem : taskSlice)
90 {
91 taskCallback(taskItem);
92 }
93 };
94
95 ParallelForInternal<ElemType>(
96 taskItems, plParallelForFunction<ElemType>(std::move(wrappedCallback), plFrameAllocator::GetCurrentAllocator()), szTaskName, params);
97}
98
99template <typename ElemType, typename Callback>
101 plArrayPtr<ElemType> taskItems, Callback taskCallback, const char* szTaskName, const plParallelForParams& params)
102{
103 auto wrappedCallback = [taskCallback = std::move(taskCallback)](plUInt32 uiBaseIndex, plArrayPtr<ElemType> taskSlice)
104 {
105 for (plUInt32 uiIndex = 0; uiIndex < taskSlice.GetCount(); ++uiIndex)
106 {
107 // Handing in by dereferenced pointer allows to use callbacks with (non-)const& as well as value parameters.
108 taskCallback(uiBaseIndex + uiIndex, *(taskSlice.GetPtr() + uiIndex));
109 }
110 };
111
112 ParallelForInternal<ElemType>(
113 taskItems, plParallelForFunction<ElemType>(std::move(wrappedCallback), plFrameAllocator::GetCurrentAllocator()), szTaskName, params);
114}
Definition ParallelFor_inl.h:8
void ExecuteWithMultiplicity(plUInt32 uiInvocation) const override
Override this to implement the task's supposed functionality.
Definition ParallelFor_inl.h:23
void Execute() override
Override this to implement the task's supposed functionality.
Definition ParallelFor_inl.h:17
Base class for all memory allocators.
Definition Allocator.h:23
This class encapsulates an array and it's size. It is recommended to use this class instead of plain ...
Definition ArrayPtr.h:37
PL_ALWAYS_INLINE plUInt32 GetCount() const
Returns the number of elements in the array.
Definition ArrayPtr.h:142
PL_FORCE_INLINE plArrayPtr< T > GetSubArray(plUInt32 uiStart, plUInt32 uiCount) const
Creates a sub-array from this array.
Definition ArrayPtr.h:148
Definition Basics.h:76
A Shared ptr manages a shared object and destroys that object when no one references it anymore....
Definition SharedPtr.h:10
Given out by plTaskSystem::CreateTaskGroup to identify a task group.
Definition TaskSystemDeclarations.h:103
Base class for custom tasks.
Definition Task.h:10
static void ParallelForSingleIndex(plArrayPtr< ElemType > taskItems, Callback taskCallback, const char *szTaskName=nullptr, const plParallelForParams &params=plParallelForParams())
Definition ParallelFor_inl.h:100
static void WaitForGroup(plTaskGroupID group)
Blocks until all tasks in the given group have finished.
Definition TaskSystemGroups.cpp:274
static void ParallelForSingle(plArrayPtr< ElemType > taskItems, Callback taskCallback, const char *szTaskName=nullptr, const plParallelForParams &params=plParallelForParams())
Definition ParallelFor_inl.h:84
static void ParallelFor(plArrayPtr< ElemType > taskItems, Callback taskCallback, const char *szTaskName=nullptr, const plParallelForParams &params=plParallelForParams())
Definition ParallelFor_inl.h:73
static plTaskGroupID StartSingleTask(const plSharedPtr< plTask > &pTask, plTaskPriority::Enum priority, plOnTaskGroupFinishedCallback callback=plOnTaskGroupFinishedCallback())
A helper function to insert a single task into the system and start it right away....
Definition TaskSystemTasks.cpp:20
constexpr PL_ALWAYS_INLINE T Min(T f1, T f2)
Returns the smaller value, f1 or f2.
Definition Math_inl.h:27
A generic delegate class which supports static functions and member functions.
Definition Delegate.h:76
Settings for plTaskSystem::ParallelFor invocations.
Definition TaskSystemDeclarations.h:167
plAllocator * m_pTaskAllocator
The allocator used to for the tasks that the parallel-for uses internally. If null,...
Definition TaskSystemDeclarations.h:186
plUInt32 m_uiBinSize
Definition TaskSystemDeclarations.h:173
@ EarlyThisFrame
Highest priority, guaranteed to get finished in this frame.
Definition TaskSystemDeclarations.h:42