Software Archive
Read-only legacy content
17060 Discussions

Controlling the number of workers by __cilkrts_set_param

Minjang_Kim
Beginner
737 Views
I'm using Intel C/C++ 64-bit compiler 12.0.3.132 with Visual Studio 2010.

I want to change the number of workers (i.e., the number of cores that will be utilized) dynamically by calling__cilkrts_set_param.

In OpenMP, it can be set by either by calling omp_set_num_threads or setting environment variable OMP_NUM_THREADS.

I think the following call should change the number of workers:
__cilkrts_set_param("nworkers", nthreads);

However, it's not working well. Its behaviors are hard to predict.
I wrote a very simple program that dynamically changes the number of workers after a lot of struggling.

[cpp]#include 
#include 

void cilk_test(const char* nthreads)
{
  __cilkrts_set_param("nworkers", nthreads);
  std::cout << "1st try: nthreads: " << nthreads
    << "; cilk: " << __cilkrts_get_nworkers()
    << std::endl;

  __cilkrts_end_cilk();
  __cilkrts_init();

  __cilkrts_set_param("nworkers", nthreads);
  std::cout << "2nd try: nthreads: " << nthreads
    << "; cilk: " << __cilkrts_get_nworkers()
    << std::endl;

  cilk_for (int i = 0; i < 10; ++i)
  {
    for (volatile int64_t k = 0; k < 500000000LL; ++k);
  }
}

int main(int argc, char* argv[])
{
  cilk_test("4");
  cilk_test("6");
  cilk_test("8");
  cilk_test("2");
  return 0;
}[/cpp]
The code looks weired, but this is needed to reset the number of workers. Here is the output on my Core i7 2600 (Sandy Bridge): 4 cores with 8 threads by hyperthreading.

1st try: nthreads: 4; cilk: 4
2nd try: nthreads: 4; cilk: 4
1st try: nthreads: 6; cilk: 4
2nd try: nthreads: 6; cilk: 6
1st try: nthreads: 8; cilk: 6
2nd try: nthreads: 8; cilk: 8
1st try: nthreads: 2; cilk: 8
2nd try: nthreads: 2; cilk: 2

It shows that the very first time __cilkrts_set_param is working. However, later calls will not immediately change the runtime. I needed to retry again.

Unfortunately, I also found that even such hack was not successful on two socket machines: 2 processors of Xeon E5656 (Westmere): total 12 cores with 12 threads (hyperthreading is disabled). So far, I can't find a way to dynamically set the number of workers on this two socket machine.

First try: nthreads: 4; cilk: 4
Second try: nthreads: 4; cilk: 4
First try: nthreads: 6; cilk: 4
Second try: nthreads: 6; cilk: 4
First try: nthreads: 8; cilk: 4
Second try: nthreads: 8; cilk: 4
First try: nthreads: 2; cilk: 4
Second try: nthreads: 2; cilk: 4

In this machine, after setting the number of workers at first, no further reseting was successful.

How can I successfully and easily change the number of workers dynamically?
0 Kudos
2 Replies
Barry_T_Intel
Employee
737 Views

Once the runtime is running, the number of workers is set. Moving the call to __cilkrts_init() to just before your cilk_for loop gives the result I think you're looking for:

1st try: nthreads: 4; cilk: 4
2nd try: nthreads: 4; cilk: 4
1st try: nthreads: 6; cilk: 4
2nd try: nthreads: 6; cilk: 6
1st try: nthreads: 8; cilk: 6
2nd try: nthreads: 8; cilk: 8
1st try: nthreads: 2; cilk: 8
2nd try: nthreads: 2; cilk: 2


Note that I ran this test with the 12.1 runtime, but the results should be the same for 12.1, Update 3.

- Barry

0 Kudos
Pablo_H_Intel
Employee
737 Views
We recognize that this behavior is strange, and it may change in the future. The only reliable way (now and in the future) to change the number of workers used by Cilk is to force the Cilk runtime to end before you set the number of workers, then set the number of workers before you restart Cilk. In other words, the Cilk runtime system must not be running when you set the number of workers. The following should give you what you want:
[cpp]   __cilkrts_end_cilk();  
   __cilkrts_set_param("nworkers", nthreads);[/cpp]
The above must be executed outside of any spawning function (i.e., a function that contains a _Cilk_spawn). (For our purposes here, a _Cilk_for loop behaves like a spawning function. The function containing the _Cilk_for does not behave like a spawning function unless it also contains a _Cilk_spawn.)

- Pablo
0 Kudos
Reply