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

task scheduler initialization

CCar
Beginner
496 Views
Does the task scheduler initialization have to be in main (or equivalent)?
I'm trying to use a TBB/IPP based library I wrote from within a wxWindows event driven program.
Seems like I'd want to do the initialization in the constructor for my specific class that uses the Intel TBB since it's the only part of the code that uses intel libraries.

I've tried it in both places and regardless, I get a runtime error in the parallel_for/blocked_range call and the MS/VS2008 debugger takes me to task.h right at the init() line in the constructor. I don't understand the error or how to debug it.

A different non-wxwindows code (with a simple main() ) for testing this library has no problem at all.
0 Kudos
4 Replies
robert-reed
Valued Contributor II
496 Views
Quoting - CCar
Does the task scheduler initialization have to be in main (or equivalent)?
I'm trying to use a TBB/IPP based library I wrote from within a wxWindows event driven program.
Seems like I'd want to do the initialization in the constructor for my specific class that uses the Intel TBB since it's the only part of the code that uses intel libraries.

I've tried it in both places and regardless, I get a runtime error in the parallel_for/blocked_range call and the MS/VS2008 debugger takes me to task.h right at the init() line in the constructor. I don't understand the error or how to debug it.

A different non-wxwindows code (with a simple main() ) for testing this library has no problem at all.

Task scheduler initialization in TBB happens with the construction of a task_scheduler_init object by a "master" thread that intends to generate work via calls such as parallel_for. This initialization must occur before the first such call and must continue to live until the TBB work is done. It sounds as if either the object you create no longer exists when the parallel_for call is made, or else the parallel_for call is being made by a non-TBB-worker-thread that has not registered itself via the creation of a task_scheduler_init object.

Perhaps you can include the text of the error in your reply?
0 Kudos
CCar
Beginner
496 Views

Task scheduler initialization in TBB happens with the construction of a task_scheduler_init object by a "master" thread that intends to generate work via calls such as parallel_for. This initialization must occur before the first such call and must continue to live until the TBB work is done. It sounds as if either the object you create no longer exists when the parallel_for call is made, or else the parallel_for call is being made by a non-TBB-worker-thread that has not registered itself via the creation of a task_scheduler_init object.

Perhaps you can include the text of the error in your reply?

The error I get is:
Unhandled exception at 0x012c115b (tbb_debug.dll) in BigCode.exe: 0xC0000005: Access violation reading location 0x000000cc. Then I click "Break".
The info in the debugger window (from the Stack Frame: BigCode.exe!tbb::track_group_context )says:
+ this 0x00126810 {my_kind=bound _my_kind_aligner=1 my_parent=0x00000000 ...} tbb::task_group_context * const

Maybe this will help you to know what the problem is.

0 Kudos
CCar
Beginner
496 Views

Task scheduler initialization in TBB happens with the construction of a task_scheduler_init object by a "master" thread that intends to generate work via calls such as parallel_for. This initialization must occur before the first such call and must continue to live until the TBB work is done. It sounds as if either the object you create no longer exists when the parallel_for call is made, or else the parallel_for call is being made by a non-TBB-worker-thread that has not registered itself via the creation of a task_scheduler_init object.

Perhaps you can include the text of the error in your reply?

Your answer prompted me to try something else, which seemed to work. That is, I put the task_scheduler_init() inside the function that calls the other functions that use the parallel_for. Maybe it was too far removed before, but I was just hoping to call it one time, instead of every time I call this function.
0 Kudos
robert-reed
Valued Contributor II
496 Views
Quoting - CCar
Your answer prompted me to try something else, which seemed to work. That is, I put the task_scheduler_init() inside the function that calls the other functions that use the parallel_for. Maybe it was too far removed before, but I was just hoping to call it one time, instead of every time I call this function.

Well, that's at least a diagnostic hint, though not necessarily the most efficient thing to do in practice. If you are certain the lifetime of the task_scheduler_init object created in the constructorspansthat of theparentfunction call described above, then perhaps the parent function is being called from a different thread, one not registered with a task_scheduler_init object. Is your program already multi-threaded through some means besides TBB?

It might be more efficient to keep the task_scheduler_init object alive in your constructed object in addition to the one you added to the parent function. The function-level object should only bump a reference count rather than creating and destroying its own set of worker threads. Even better would be to instantiate an init object whose lifetime is from the first constructor call to the end of the program; trashing the thread pool every time your library object goes away may still be putting an unnecessary drag on the system.

0 Kudos
Reply