Controlling the number of workers by __cilkrts_set_param

Controlling the number of workers by __cilkrts_set_param

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.

#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;
}

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: 42nd try: nthreads: 4; cilk: 41st try: nthreads: 6; cilk: 42nd try: nthreads: 6; cilk: 61st try: nthreads: 8; cilk: 62nd try: nthreads: 8; cilk: 81st try: nthreads: 2; cilk: 82nd 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: 4Second try: nthreads: 4; cilk: 4First try: nthreads: 6; cilk: 4Second try: nthreads: 6; cilk: 4First try: nthreads: 8; cilk: 4Second try: nthreads: 8; cilk: 4First try: nthreads: 2; cilk: 4Second 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?

3 posts / 0 nouveau(x)
Dernière contribution
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.

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

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:

   __cilkrts_end_cilk();  
   __cilkrts_set_param("nworkers", nthreads);

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

Laisser un commentaire

Veuillez ouvrir une session pour ajouter un commentaire. Pas encore membre ? Rejoignez-nous dès aujourd’hui