Commit 81fd4c05 by Tobias Fuchs

algorithms_cpp: using block size partitioner in ForEach

parent 1ed7535d
...@@ -47,48 +47,54 @@ class ForEachFunctor { ...@@ -47,48 +47,54 @@ class ForEachFunctor {
/** /**
* Constructs a for-each functor with arguments. * Constructs a for-each functor with arguments.
*/ */
ForEachFunctor(RAI first, RAI last, Function unary, ForEachFunctor(size_t chunk_first, size_t chunk_last, Function unary,
const embb::mtapi::ExecutionPolicy& policy, size_t block_size) const embb::mtapi::ExecutionPolicy& policy,
: first_(first), last_(last), unary_(unary), policy_(policy), const BlockSizePartitioner<RAI>& partitioner)
block_size_(block_size) { : chunk_first_(chunk_first), chunk_last_(chunk_last),
unary_(unary), policy_(policy), partitioner_(partitioner) {
} }
void Action(mtapi::TaskContext& context) { void Action(mtapi::TaskContext&) {
size_t distance = static_cast<size_t>(std::distance(first_, last_)); if (chunk_first_ == chunk_last_) {
if (distance == 0) return; // Leaf case, recursed to single chunk. Do work on chunk:
if (distance <= block_size_) { // leaf case -> do work ChunkDescriptor<RAI> chunk = partitioner_[chunk_first_];
for (RAI it = first_; it != last_; ++it) { RAI first = chunk.GetFirst();
RAI last = chunk.GetLast();
for (RAI it = first; it != last; ++it) {
unary_(*it); unary_(*it);
} }
} else { // recurse further }
ChunkPartitioner<RAI> partitioner(first_, last_, 2); else {
ChunkDescriptor<RAI> chunk_l = partitioner[0]; // Recurse further:
ChunkDescriptor<RAI> chunk_r = partitioner[1]; size_t chunk_split_index = (chunk_first_ + chunk_last_) / 2;
self_t functor_l(chunk_l.GetFirst(), // Split chunks into left / right branches:
chunk_l.GetLast(), self_t functor_l(chunk_first_,
unary_, policy_, block_size_); chunk_split_index,
self_t functor_r(chunk_r.GetFirst(), unary_, policy_, partitioner_);
chunk_r.GetLast(), self_t functor_r(chunk_split_index + 1,
unary_, policy_, block_size_); chunk_last_,
// Spawn tasks for right partition first: unary_, policy_, partitioner_);
mtapi::Task task_l = mtapi::Node::GetInstance().Spawn(
mtapi::Action(
base::MakeFunction(
functor_l, &ForEachFunctor<RAI, Function>::Action),
policy_));
mtapi::Task task_r = mtapi::Node::GetInstance().Spawn( mtapi::Task task_r = mtapi::Node::GetInstance().Spawn(
mtapi::Action( mtapi::Action(
base::MakeFunction( base::MakeFunction(
functor_r, &ForEachFunctor<RAI, Function>::Action), functor_r, &ForEachFunctor<RAI, Function>::Action),
policy_)); policy_));
// Recurse on left partition:
functor_l.Action(context);
// Wait for tasks on right partition to complete:
task_r.Wait(MTAPI_INFINITE); task_r.Wait(MTAPI_INFINITE);
task_l.Wait(MTAPI_INFINITE);
} }
} }
private: private:
RAI first_; size_t chunk_first_;
RAI last_; size_t chunk_last_;
Function unary_; Function unary_;
const embb::mtapi::ExecutionPolicy& policy_; const embb::mtapi::ExecutionPolicy& policy_;
size_t block_size_; const BlockSizePartitioner<RAI>& partitioner_;
/** /**
* Disables assignment. * Disables assignment.
...@@ -112,12 +118,17 @@ void ForEachRecursive(RAI first, RAI last, Function unary, ...@@ -112,12 +118,17 @@ void ForEachRecursive(RAI first, RAI last, Function unary,
block_size = 1; block_size = 1;
} }
} }
// Perform check of task number sufficiency // Perform check of task number sufficiency
if (((distance / block_size) * 2) + 1 > MTAPI_NODE_MAX_TASKS_DEFAULT) { if (((distance / block_size) * 2) + 1 > MTAPI_NODE_MAX_TASKS_DEFAULT) {
EMBB_THROW(embb::base::ErrorException, "Not enough MTAPI tasks available " EMBB_THROW(embb::base::ErrorException, "Not enough MTAPI tasks available "
"to perform the parallel foreach loop"); "to perform the parallel foreach loop");
} }
ForEachFunctor<RAI, Function> functor(first, last, unary, policy, block_size);
BlockSizePartitioner<RAI> partitioner(first, last, block_size);
ForEachFunctor<RAI, Function> functor(0,
partitioner.Size() - 1,
unary, policy, partitioner);
mtapi::Task task = node.Spawn(mtapi::Action( mtapi::Task task = node.Spawn(mtapi::Action(
base::MakeFunction(functor, base::MakeFunction(functor,
&ForEachFunctor<RAI, Function>::Action), &ForEachFunctor<RAI, Function>::Action),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment