2

I am trying to manage the count of native threads in PPL by using its Scheduler class, here is my code:

for (int i = 0; i < 2000; i ++)
{
    // configure concurrency count 16 to 32.
    concurrency::SchedulerPolicy policy = concurrency::SchedulerPolicy(2, concurrency::MinConcurrency, 16, 
            concurrency::MaxConcurrency, 32);
    concurrency::Scheduler *pScheduler = concurrency::Scheduler::Create(policy);
    HANDLE hShutdownEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    pScheduler->RegisterShutdownEvent(hShutdownEvent);
    pScheduler->Attach();

    //////////////////////////////////////////////////////////////////////////

    //for (int i = 0; i < 2000; i ++)
    {
        concurrency::create_task([]{
            concurrency::wait(1000);
            OutputDebugString(L"Task Completed\n");
        });
    }

    //////////////////////////////////////////////////////////////////////////

    concurrency::CurrentScheduler::Detach();
    pScheduler->Release();
    WaitForSingleObject(hShutdownEvent, INFINITE);
    CloseHandle(hShutdownEvent);
}

The usage of SchedulerPolicy is from MSDN, but it didn't work at all. The expected result of my code above is, PPL will launch 16 to 32 threads to execute the 2000 tasks, but the fact is:

By observing the speed of console output, only one task was processed within a second. I also tried to comment the outter for loop and uncomment the inner for loop, however, this will cause 300 threads being created, still incorrect. If I wait a longer time, the threads created will be even more.

Any ideas on what is the correct way to configure concurrency in PPL?

Hao Xi
  • 351
  • 4
  • 12
  • One possible reason is the `WaitForSingleObject` call will block each loop from completion, which will cause the loop being executed for 1 second each time. But what is the correct way? – Hao Xi Nov 22 '16 at 06:38

1 Answers1

3

It has been proved that I should not do concurrency::wait within the task body, PPL works in work stealing mode, when the current task was suspended by wait, it will start to schedule the rest of tasks in queue to maximize the use of computing resources.

When I use concurrency::create_task in real project, since there are a couple of real calculations within the task body, PPL won't create hundreds of threads any more.

Also, SchedulePolicy can be used to configure the number of virtual processors that PPL may use to process the tasks, which is not always same as the number of native threads PPL will create.

Saying my CPU has 8 virtual processors, by default PPL will just create 8 threads in pool, but when some of those threads were suspended by wait or lock, and also there are more tasks pending in the queue, PPL will immediately create more threads to execute them (if the virtual processors were not fully loaded).

Hao Xi
  • 351
  • 4
  • 12