PPL - 如何配置本机线程数?

时间:2016-11-22 06:28:45

标签: c++ windows multithreading threadpool ppl

我试图通过使用Scheduler类来管理PPL中的本机线程数,这是我的代码:

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

SchedulerPolicy的使用来自MSDN,但它根本不起作用。我上面代码的预期结果是,PPL将启动16到32个线程来执行2000个任务,但事实是:

通过观察控制台输出的速度,在一秒钟内只处理了一个任务。我还试图评论out for循环并取消注释内部for循环,但是,这将导致创建300个线程,仍然不正确。如果我wait时间更长,创建的线程将会更多。

有关在PPL中配置并发的正确方法的任何想法吗?

1 个答案:

答案 0 :(得分:1)

已经证明我不应该在任务主体内concurrency::wait,PPL在工作窃取模式下工作,当当前任务被wait暂停时,它将开始安排剩下的队列中的任务,以最大限度地利用计算资源。

当我在实际项目中使用concurrency::create_task时,由于在任务主体中有几个真实的计算,PPL将不再创建数百个线程。

此外,SchedulePolicy可用于配置PPL可用于处理任务的虚拟处理器数量,这与PPL将创建的本机线程数量并不总是相同。

说我的CPU有8个虚拟处理器,默认情况下PPL只会在池中创建8个线程,但当其中一些线程被waitlock挂起时,还有更多待处理的任务在队列中,PPL将立即创建更多线程来执行它们(如果虚拟处理器未完全加载)。