Community
cancel
Showing results for 
Search instead for 
Did you mean: 
DweeberlyLoom
Beginner
78 Views

task reuse (recycle) question

This seems like a simple question but I'm having a devil of a time getting the details correct.

What I'd like to do is createatask class, lets call it "FooTask"that I can instantiate and task allocate once, then spawn repeatly (as needed). For example:

struct FooTask: public task {
Data *_dt;
FooTask() { }
void SetData(Data *data) {
_dt = data;
}
task* execute() {
// do stuff with data
}
};

FooTask *tk1 = 0, *tk2 = 0;
void Fooing(Data *data) {
if (tk1 == 0) {
// construct and call task allocate (of some form) on tk1 and tk2
}
if (tl1->state() != task::executing) {
tk1->SetList(data);
tk1->spawn(*tk1); // may not be the correct call/syntax
}
else if (tk2->state() == task::executing) {
tk2->SetList(data);
tk2->spawn(*tk2); // may not be the correct call/syntax
}
else {
// do something else with data
}
}

I've tried various sorts of allocations and recycle_as's but I always end up with some sort of assertion hit. I've pretty much convinced myself that I need to change this to some sort of pipeline or queue, but I'm nowcurious how one would implement this pattern in C++ w/ TBB. Can anyone provide an example or an explaination of my "wrongheadedness"?

Thanks

0 Kudos
4 Replies
robert-reed
Valued Contributor II
78 Views

TBB offers such features as task recycling and continuation to avoid some of the overhead associated with task scheduling. The goal therefore is to avoid the spawn calls altogether. It's not clear to me how the code presented above attempts to meetsuch a goal, nor what isthe underlying motivation for using TBB. Do you have a particular algorithm for which you're trying to write parallel code? It's hard for me to answer your question about pipelines or queues without having a better idea about what you're really trying to do.

DweeberlyLoom
Beginner
78 Views

mad reed:

TBB offers such features as task recycling and continuation to avoid some of the overhead associated with task scheduling. The goal therefore is to avoid the spawn calls altogether. It's not clear to me how the code presented above attempts to meetsuch a goal, nor what isthe underlying motivation for using TBB. Do you have a particular algorithm for which you're trying to write parallel code? It's hard for me to answer your question about pipelines or queues without having a better idea about what you're really trying to do.

Thank you for replying. I should not have brought up the pipelines or queues, I know how to implement the requiredlogic forthose.

I'm really just interested in how to implement simple task reuse.For examplelets say I have five different (independent)database connections open and I want to set up five tasks (one for each connection). I'd like to be able to send thetask some data and let it update the DB as it can. Or perhaps I would want to implement some sort of"lazy" memory free/delete/dispose, where I hand off a pointer and let the(complex) datastructure it pointsto get freed without having to wait around. I suppose it's a producer -consumer sorta thing.I want to call (set data on the object, the start the task), as needed, without incurring the repeatedcost of task and object creation. I'd like to create the object and task once, then reuse it (throw it back into scheduling)when I need to.

ARCH_R_Intel
Employee
78 Views

TBB tasks are designed to be fast to create, so it'softennot worth the trouble to recycle them. I timed aa simple recursiveparallelism example and it took ~310 clock cycles to create, spawn, run,and destroy each task. Only about ~90 of those cycle are for creating and destroying the task.

There are methods for recycling tasks in TBB, such as task::recycle_as_child_of. Those methods exist primarily to save the overhead of copying user objects associated with the task. E.g., see how task::recycle_as_child_of is used in "tbb/parallel_for.h" to avoid copyingthe user'srange and body objects. The recycling methods target specific idioms.

If you have heavy-weight objects, then the best route may be to make the object separate from the task, and when you need to schedule work involving the object, create and spawn a task with a pointer/reference to the heavy object.

DweeberlyLoom
Beginner
78 Views

Thanks, I understand better now.
Reply