- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I recently converted the main path of my code to use TBB flow graph, previously I was using combinations of parallel_for and serial code. In addition to this my codebase contains longer running tasks in a seperate task_group which are not waited on, they finish when they finish.
Unfortunatly I am seeing a big problem with performance, each call to graph.wait_for_all() is taking much longer than it should.
My first guess is that somehow wait_for_all() is waiting on my long running tasks, this essentially brings my program to a crawl(it is a video game).
Assuming that this is the case, is there any way to make flow graph only work on the tasks I've given it?
Or is there some other explanation for why flow graph causes such horrible slow down?
Is flow graph suited for a real time application?
Thanks
PS. This forum is really bad at formating text, it removes all line spaces :(
Link Copied
6 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Flow graph is based on enqueued tasks (not spawned tasks like parallel_for), and perhaps these are now intermingled with the longer-running tasks on a first-come first-served basis. Try to enqueue the latter on a lower-priority basis, using tbb::priority_low. Does that make a difference?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Raf,
I switched my long running tasks to using enque + low priority, like this..
tbb::task::enqueue(*t,tbb::priority_low);
But this does not appear to help, pausing the program shows that the main thread which called graph.wait_for_all() is indeed running a long running task.
Is there anything else I can do with TBB itself to prevent this?
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I thought I might be able to use affinity to mask out the main thread from running long running tasks, but it seems enque does not work with set_affinity(), as it said asserted with"affinity is ignored for enqueued tasks".
So I tried switching the long running tasks to spawn() + set_affinity(0xFFFE) but this informs me that the mask is out of range, looking at the code it appears that affinity can only be used to set the specific thread, and not as a thread mask.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry, it seemed worth trying. If you don't get the right answer soon, I may have another look at it later.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I tried making it so that if the main thread picked up a long running task it would resubmit it and return.. ( i did have to make a slight change to a TBB header so that I could get the thread ID).
auto id =tbb::this_tbb_thread::get_id().yes_i_want_the_id();
if(id== g_MainThreadID)
{
TBB_Job* t = new( tbb::task::allocate_root() ) TBB_Job
tbb::task::enqueue(*t,tbb::priority_low);
}
else
{
_Job();
}
return nullptr;
Since I had to modify a TBB header I'm not sure if this qualifies as a fix, but it does work...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting foxtoxer
...pausing the program shows that the main thread which called graph.wait_for_all() is indeed running a long running task.
Is there anything else I can do with TBB itself to prevent this?
This problmeaffects not only graph by the way; each TBB algorithms eventually waits for tasks that it starts. Therefore, you better avoid long running tasks with TBB. I believe long-running jobs can almost always besplit into some stages done by different tasks. E.g. if a job contains a serial loop, each iteration of the loop can start as a task; at the end, it will produce (or recycle itselfinto) a task for the next iteration. The only case where a long job cannot be split is long waiting (e.g. for I/O); and waiting is better done with special threads, not with(in) TBB tasks.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page