Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.

More threads created than expected with task_scheduler_init

e4lam
Beginner
1,331 Views
It appears that in TBB 3.0, giving tbb::task_scheduler_init() a thread count less than the default number of threads still results it in creating the default number of threads. Debugging the code somewhat, I narrowed it down to market::global_market() where we have this line:
max_num_workers = max( governor::default_num_threads() - 1, max_num_workers );

Is this line necessary? If so, what do I do if I want to bypass this behaviour? Is recompiling with __TBB_ARENA_PER_MASTER set to 0 a viable alternative?

Thanks,
-Edward
0 Kudos
23 Replies
Alexandr_K_Intel1
278 Views

There seems to be *still* no one way to enforce sequential execution? I was excited to find the global_control preview class but it enforces a minimum value of 2 (? at least that's what is documented).

This is temporary restriction, we are going to remove it. Our plan is to support value 1 that serializes everything except for enqueue usage, where additional workers thread created to process enqueued tasks. Is it fit your needs?

0 Kudos
e4lam
Beginner
278 Views

Alexandr Konovalov (Intel) wrote:
This is temporary restriction, we are going to remove it. Our plan is to support value 1 that serializes everything except for enqueue usage, where additional workers thread created to process enqueued tasks. Is it fit your needs?

That sounds perfectly reasonable because enqueue is meant for things like std::future. Is there a rough time frame as to when this would make it into a stable release? Thanks!

PS. A tbb::future wrapper might be a useful addition to TBB as well because it doesn't make sense for applications using TBB to use std::future when you've already got a task scheduler to avoid over subscription.

0 Kudos
RafSchietekat
Valued Contributor III
278 Views

A future doesn't have any say in how its value is computed. You even have to do desperate things to be able to "steal" the work if it's still just sitting there by the time you need the result. (Note that a TBB thread "steals" any work it finds just to keep busy, not necessarily what it needs first, so that's a different concept.) You can roll your own TBB-based async(), so to say, by enqueue()'ing a task and letting it set the value of a corresponding promise; there's nothing for TBB to provide here.

But a future is also a poor substitute for a dependency. In TBB, your instinct should be to have a continuation and a child task, where the continuation is scheduled automatically when the child task has finished execution and probably delivered the result to the continuation, not to just have one thread block waiting for a result to be delivered by another thread. You can use a future to interface with TBB from a different threading model, with TBB on the promise side of the equation, but you definitely shouldn't be accessing a future from within a TBB thread.

Or did you have something else in mind?

0 Kudos
Reply