Is there anything similar to PPL's task continuations in TBB?
I am aware of the low level TBB method of manuall allocating tbb::task
s and manually allocating continuation tasks too and managing ref counts manually for them:
struct FibContinuation: public task {
long* const sum;
long x, y;
FibContinuation( long* sum_ ) : sum(sum_) {}
task* execute() {
*sum = x+y;
return NULL;
}
};
struct FibTask: public task {
const long n;
long* const sum;
FibTask( long n_, long* sum_ ) :
n(n_), sum(sum_)
{}
task* execute() {
if( n<CutOff ) {
*sum = SerialFib(n);
return NULL;
} else {
// long x, y; This line removed
FibContinuation& c =
*new( allocate_continuation() ) FibContinuation(sum);
FibTask& a = *new( c.allocate_child() ) FibTask(n-2,&c.x);
FibTask& b = *new( c.allocate_child() ) FibTask(n-1,&c.y);
// Set ref_count to "two children plus one for the wait".
c.set_ref_count(2);
spawn( b );
spawn( a );
// *sum = x+y; This line removed
return NULL;
}
}
};
That's simply horrible. You have to in advance know how many child tasks you will spawn, and manually set the reference count appropriately. This is very fragile coding...
PPL's way of specifying continuations is just so straightforward:
create_task([]()->bool
{
// compute something then return a bool result
return true
}).then([](bool aComputedResult)
{
// do something with aComputedResult
});
How do you achieve that in TBB?
Yes, there are several recommended TBB continuation styles you can read about at http://www.threadingbuildingblocks.org/docs/help/reference/task_scheduler/catalog_of_recommended_task_patterns.htm. However, by design of the TBB library, none of them use C++11 constructs like your PPL example.
If your question is really "does TBB have a C++11 interface for task continuation," then the answer is "no."
There isn't anything directly, I posted an example of how to do this with task_group (which is in tbb) ages ago on my blog here.
The syntax is similar but not 100% the same since it was posted before task existed.
void SimpleContinuation()
{
auto task1 = run_task([](){ContinueableTask(1);});
//task 2 depends on task 1
auto task2 = run_when(task1, [](){ContinueableTask(2);});
wait_for_all(task1, task2);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With