28 #include <gts/micro_scheduler/WorkerPool.h>
29 #include <gts/micro_scheduler/MicroScheduler.h>
33 namespace gts_examples {
47 myCell.sum += (ii != 0 ? grid[ii-1][jj].sum : 0) + (jj != 0 ? grid[ii][jj-1].sum : 0);
49 bool hasBottomSuccessor = (ii + 1 < width) && (grid[ii+1][jj].dependecies.fetch_sub(1, memory_order::acq_rel) - 1 == 0);
50 bool hasRightSuccessor = (jj + 1 < height) && (grid[ii][jj+1].dependecies.fetch_sub(1, memory_order::acq_rel) - 1 == 0);
53 if(hasBottomSuccessor || hasRightSuccessor)
61 uint32_t refCount = (hasBottomSuccessor ? 1 : 0) + (hasRightSuccessor ? 1 : 0);
62 pContinuation->
addRef(refCount, memory_order::relaxed);
64 if (hasBottomSuccessor)
71 if (hasRightSuccessor)
83 void stronglyDynamicTaskGraph_wavefront(
int width,
int height)
85 printf (
"================\n");
86 printf (
"stronglyDynamicTaskGraph_wavefront\n");
87 printf (
"================\n");
120 result = microScheduler.
initialize(&workerPool);
123 auto start = std::chrono::high_resolution_clock::now();
126 GridCell** grid =
new GridCell*[width];
127 for (
int ii = width - 1; ii >= 0; --ii)
129 grid[ii] =
new GridCell[height];
131 for (
int jj = height - 1; jj >= 0; --jj)
133 grid[ii][jj].dependecies.store((ii > 0) + (jj > 0), memory_order::relaxed);
140 Task* pTask = microScheduler.
allocateTask(calcuateSum, grid, 0, 0, width, height);
143 printf(
"Sum: %" PRIu64
"\n", grid[width-1][height-1].sum);
145 for (
int ii = width - 1; ii >= 0; --ii)
151 auto end = std::chrono::high_resolution_clock::now();
152 std::cout <<
"Time (ms): " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << std::endl;
156 void wavefront(uint64_t** grid,
int ii,
int jj,
int dimensions)
158 for (
int x = ii; x < ii + dimensions; ++x)
160 for (
int y = jj; y < jj + dimensions; ++y)
162 grid[x][y] += (x > 0 ? grid[x-1][y] : 0) + (y > 0 ? grid[x][y-1] : 0);
168 Task* wavefrontDivAndConq(uint64_t** grid,
int ii,
int jj,
int dimensions,
TaskContext const& ctx)
170 if (dimensions <= 16)
172 wavefront(grid, ii, jj, dimensions);
176 int halfDim = dimensions / 2;
187 pContinuation->
addRef(2, memory_order::relaxed);
205 void stronglyDynamicTaskGraph_divideAndConquerWavefront(
int dim)
207 printf (
"================\n");
208 printf (
"stronglyDynamicTaskGraph_divideAndConquerWavefront\n");
209 printf (
"================\n");
234 result = microScheduler.
initialize(&workerPool);
237 auto start = std::chrono::high_resolution_clock::now();
239 uint64_t* buffer =
new uint64_t[dim*dim];
240 uint64_t** grid =
new uint64_t*[dim];
241 for (
int ii = 0; ii < dim; ++ii)
243 grid[ii] = buffer + dim * ii;
244 memset(grid[ii], 0,
sizeof(uint64_t) * dim);
249 Task* pTask = microScheduler.
allocateTask(wavefrontDivAndConq, grid, 0, 0, dim);
252 printf(
"Sum: %" PRIu64
"\n", grid[dim-1][dim-1]);
257 auto end = std::chrono::high_resolution_clock::now();
258 std::cout <<
"Time (ms): " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << std::endl;
A empty Task that can be used as dummy or placeholder.
Definition: Task.h:355
A work-stealing task scheduler. The scheduler is executed by the WorkerPool it is initialized with.
Definition: MicroScheduler.h:81
void spawnTaskAndWait(Task *pTask, uint32_t priority=0)
Spawns the specified 'pTask' to be executed by the scheduler and then waits for its reference count t...
void spawnTask(Task *pTask, uint32_t priority=0)
Spawns the specified 'pTask' to be executed by the scheduler. Spawned tasks are executed in LIFO orde...
bool initialize(WorkerPool *pWorkerPool)
Initializes the MicroScheduler and attaches it to pWorkPool, where each worker in pWorkPool will exec...
GTS_INLINE TTask * allocateTask(TArgs &&... args)
Allocates a new Task object of type TTask.
Definition: MicroScheduler.h:145
A Task payload that embeds TFunc and TArgs into the Task's data. It makes it easy to construct a Task...
Definition: Task.h:120
GTS_INLINE void setContinuationTask(Task *pContinuation)
Definition: Task.inl:48
void spawnAndWaitForAll(Task *pChild)
GTS_INLINE int32_t addRef(int32_t count=1, gts::memory_order order=gts::memory_order::seq_cst)
Definition: Task.inl:84
GTS_INLINE void addChildTaskWithoutRef(Task *pChild)
Definition: Task.inl:30
A collection of running Worker threads that a MicroScheduler can be run on.
Definition: WorkerPool.h:54
bool initialize(uint32_t threadCount=0)
#define GTS_ASSERT(expr)
Causes execution to break when expr is false.
Definition: Assert.h:144
The context associated with the task being executed.
Definition: MicroSchedulerTypes.h:54
Task * pThisTask
The current task.
Definition: MicroSchedulerTypes.h:71
MicroScheduler * pMicroScheduler
The MicroScheduler executing the Task.
Definition: MicroSchedulerTypes.h:59
Definition: 7_strongly_dynamic_task_graph_wavefront.h:38