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

Best way to correctly change the number of threads during app running

hnder
Beginner
2,210 Views
What is the best way to change the number of threads used in tbb? I want to have dll that exports the function that sets the number of threads. If I call this function with N threads and run tbb::parallel_for(...) it should use only N threads after that. I need to call it several times with different N. So I create a global object tbb::global_control. I modify it in this function. Like this:
 

 

tbb::global_control g = tbb::global_control(                                  
          tbb::global_control::max_allowed_parallelism, 
          tbb::info::default_concurrency());

EXPORT_MY_API void set_max_threads_num(int threads_num)
{          
     g = tbb::global_control(
         tbb::global_control::max_allowed_parallelism, 
         threads_num);
}

 

 
But for me it looks not good. And I have experienced some crashes and not stable behavior of re-initializing this global control. Sometimes I get this assertion from tbb code:
 
 Assertion lhs->my_param < global_control::parameter_max failed (located in the operator () function, line in file: 157)
 
Any hints about correct way of using global_control for modifying threads number?
0 Kudos
8 Replies
SeshaP_Intel
Moderator
2,168 Views

Hi,

 

Thank you for posting in Intel Communities.

 

I have created the function that sets the number of threads and created a global_control object in the mytbbdll.cpp file and am able to call the function with N threads in the main.cpp file.

I did not face any issues, please find the attachment(Source.zip) below. I have run the following commands.

 

icx /LD mytbbdll.cpp -Qtbb
icx main.cpp -Qtbb

 

You can call the setMaxThreadsNum() function several times with different N values.

Could you please provide the complete reproducer code and the steps you followed where it lead to the crash so that we can investigate the issue from our end? 

 

Thanks and Regards,

Pendyala Sesha Srinivas

hnder
Beginner
2,142 Views

Hi Sesha,

 

Thanks for replying.

May be there is a problem in my environment.

I was able to reproduce the issue just by creating exe file without dll. See main.cpp from main.7z.

 

My environment:

1) I use Microsoft Visual Studio Professional 2022 (64-bit) - Version 17.5.5

2) I have oneAPI version 2021.9.0 installed. C:\Program Files (x86)\Intel\oneAPI\tbb\2021.9.0

 

Steps:

1) Create Empty project (C++, Windows, Console) in Visual Studio. Project1 as a name for example.

2)  Copy main.cpp (from main.7z) into project directory and add it to project.

3)  In Project settings add tbb include directories:

C/C++ -> General -> Additional Include Directories -> C:\Program Files (x86)\Intel\oneAPI\tbb\2021.9.0\include

3)  In Project settings add tbb lib directories:

Linker -> General -> Additional Library Directories -> C:\Program Files (x86)\Intel\oneAPI\tbb\2021.9.0\lib\intel64\vc14

4) In Project settings add post build event (to run exe automatically after build):

Build Events -> Post-Build Event -> $(TargetPath)

5) Build in Release and Debug mode. 

6) It will need tbb dlls to run. I copy them from here C:\Program Files (x86)\Intel\oneAPI\tbb\2021.9.0\redist\intel64\vc14

Copy tbb_debug.dll into Project1\x64\Debug

Copy tbb.dll into Project1\x64\Release

 

I have attached Project1.7z for reference. My paths in project can be different from yours.

 

Problem:

1) If I re-build in Release mode sometime (not everytime!) I have got assertion as in Assertion_Release.png:

Assertion lhs->my_param < global_control::parameter_max failed (located in the operator () function, line in file: 157)

2) In Debug mode I have got assertion as Assertion_Debug.png

 

I found out that problem in Release looks like disapeared if I comment printf line here. It's strange for me.

 

 

void set_max_threads_num(int threads_num)
{
	//printf("Setting max threads num %d\n", threads_num);

	global_control = tbb::global_control(
		tbb::global_control::max_allowed_parallelism,
		threads_num);
}

 

If I don't change number of threads (set the same number) everything is OK.

void set_max_threads_num(int threads_num)
{
	printf("Setting max threads num %d\n", threads_num);
	threads_num = 2;

	global_control = tbb::global_control(
		tbb::global_control::max_allowed_parallelism,
		threads_num);
}

 

Maybe I did something wrong?

0 Kudos
SeshaP_Intel
Moderator
2,078 Views

Hi,

 

Could you please try with below code and let us know the results?

void set_max_threads_num(int threads_num)
{
	printf("Setting max threads num %d\n", threads_num);
	oneapi::tbb::global_control global_control = oneapi::tbb::global_control(oneapi::tbb::global_control::max_allowed_parallelism,threads_num);
}

We have tried to build in both Debug and Release mode and we did not face any issues.

Please let us know if you still face any issues.

 

Thanks and Regards,

Pendyala Sesha Srinivas

0 Kudos
hnder
Beginner
2,065 Views

Hi,

 

With this code I don't have issues, but this code doesn't make sense to me as object is constructed inside function and destroyed after exit of the function. So, setting the number of threads doesn't work in this way. That's why I made this object as global. But this leads to problems I indicated above.

0 Kudos
SeshaP_Intel
Moderator
1,976 Views

Hi,


We were able to reproduce the issue in Debug mode. We are working on this internally.

We will get back to you soon.


Thanks and Regards,

Pendyala Sesha Srinivas


0 Kudos
Pavel_K_Intel1
Employee
1,960 Views

Hi,
I am not sure if the global_control support this type of usage (because if instants of global_control keeps a reference on the library).
Usually you will use it as a stack variable that will wrap the parallel region. Can you try to do the same by adding the global stack that will manage life time of global_control or if your application does not expect inner global_control try to manage it dynamically e.g. call new and delete each time you are going to set new global_control.

0 Kudos
hnder
Beginner
1,858 Views
0 Kudos
SeshaP_Intel
Moderator
1,831 Views

Hi,


Thanks for the confirmation. This thread will no longer be monitored by Intel. If you need further assistance, please post a new question.


Thanks and Regards,

Pendyala Sesha Srinivas


0 Kudos
Reply