- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What I would like to do is something along the lines of:
[cpp]while(!my_future.is_ready()) tbb::task_scheduler::yield(); // If the calling context is inside an executing tbb task then run some other tasks.[/cpp]or
[cpp]tbb::task_scheduler::oversubscribe(true); // If the calling context is inside an executing tbb task then insert another thread into task-scheduler. my_future.wait(); tbb::task_scheduler::oversubscribe(false);[/cpp]Is any of these or similar solutions possible with the current revision of tbb? Any suggestions in regards to work-arounds?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Why? External library? Difficult colleague? :-)
How about a user thread whose sole purpose it is to wait for the future and then decrement a reference count that you wait for in the task? A deferred status may indicate that getting the value won't block, but it provides only shallow information, so you may want to experiment either way on a case-by-case basis: probably it won't block, but the penalty (of undersubscription) is higher. (Obtain the thread from a pool and park it there after use.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Unfortunately I do not understand your solution suggestion. Would you care to give a bit more detailed explanation?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Instead of just executing the future::get() inside a task, you would delegate that to an ad-hoc thread taken from a pool. The handover would be the "condition variable".
The pool thread would not just execute the get() itself, though, it would wait for the status to become "ready" (nothing more to be done except use the value) or determine it as "deferred" (get() executes some code, like a function call). I now realise that either may have some blocking code, the former in the form of some essential member function to be executed anyway that involves another future or the like, but still more likely with the latter. If you encounter such recursive blocking, you could deal with it in the same manner as you encounter it, or you could decide to have that pool thread prepare the value first before the receiving task takes over; the former requires adapting all the futures at once in the same manner, the latter requires dealing with maybe fewer code but going deeper, so it's a trade-off.
In any case, mixing those paradigms/resolving the impedance mismatch should make you be able to kill quite some time...
Does that make sense, and do you agree with the approach (asking other readers at the same time)?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Anton Malakhov (Intel) wrote:
Not yet, however, we are looking into implementing something like in your 2nd code snippet.
Is there any update on this?
Following http://software.intel.com/en-us/forums/topic/393172, I need a task yield function (not thread yield) or a mechanism to wait for a non-TBB thread to finish work.
I am currently creating a dummy TBB task and waiting for the dummy task to finish (following Raf's comment in http://software.intel.com/en-us/forums/topic/393172), hoping this will cause the waiting task to yield (something like the code below). This at least helps to work around the stall issue in http://software.intel.com/en-us/forums/topic/393172 but looks not very pretty and whether this will work or not depends on implementation details. I wonder there is a better more standard way to do this.
I considered using a condition variable (supported by TBB, http://software.intel.com/en-us/blogs/2010/10/01/condition-variable-support-in-intel-threading-building-blocks), but it seems like waiting on a condition variable causes the thread to block (not a task to block).
void dummyTask( void ) {
retrun;
}
task_group dummyGroup;
while( true ) {
dummyGroup.run( []{ dummyTask(); } );
dummyGrouop.wait();
if( the non-TBB thread finished the work ) {
break;
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It won't do to wait for a dummy task, you have to make it a child of a continuation, otherwise the thread will still block, including all tasks buried below the current task. A function to temporarily oversubscribe could serve some purposes, but there's no magic to yield the stack while waiting for an asynchronous event. I think we're stuck with that for now.
Perhaps TBB could add a function to avoid the dummy child, because just calling decrement_ref_count() doesn't wake up the parent, but that's about it.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page