2

我开始使用 PPL 创建任务并将它们 [可能] 分派给其他线程,如下所示:

Concurrency::task_group  tasks;
auto simpleTask = Concurrency::make_task(&simpleFunction);
tasks.run(simpleTask);

我尝试了一个每秒创建一个任务的小应用程序。任务在 5 秒内执行繁重的计算,然后停止。

我想知道 PPL 在我的机器上创建了多少线程,以及机器的负载是否会影响线程数或分配给线程的任务。当我在 12 核机器上运行我的应用程序的一个或多个实例时,我注意到这一点:

  • 运行 1 个应用程序时,它会创建 6 个线程。总 CPU 使用率为 50%。
  • 运行 2 个应用程序时,它们都创建 6 个线程。总 CPU 使用率为 100%,但我的机器反应灵敏。
  • 当运行 3 个应用程序时,它们都创建了 6 个线程(总共已经 18 个线程)。总 CPU 使用率为 100%。
  • 运行 4 个应用程序时,我总共已经有 24 个线程。

我使用 Process Explorer 和 4 个应用程序调查了正在运行的应用程序,我可以清楚地看到它们都有 6 个(有时甚至 12 个)线程,它们都试图消耗尽可能多的 CPU。

PPL 允许您通过配置默认调度程序来限制线程数,如下所示:

Concurrency::SchedulerPolicy policy(1, Concurrency::MaxConcurrency,2);
Concurrency::Scheduler::SetDefaultSchedulerPolicy(policy);

有了这个,您可以静态限制线程数(在这种情况下为 2)。如果您事先知道在具有 24 个内核的服务器上同时有 10 个用户(因此您可以将每个应用程序限制为 2 个线程),这会很方便,但是如果 10 个用户中的一个工作到很晚,他仍然只使用 2 个线程,当机器的其余部分处于空闲状态时。

我的问题:有没有办法配置 PPL,以便它根据机器的负载动态决定创建多少线程(或保持活动或保持活动)?或者 PPL 默认情况下是否已经这样做了,我的观察结果不正确。

编辑:我尝试启动我的测试应用程序的更多实例,虽然我的机器仍然非常敏感(我在原来的问题中错了)我看不到应用程序减少了它们同时操作的数量。

4

1 回答 1

2

您的问题的简短回答是“不”。默认的 PPL 调度程序和资源管理器将仅使用进程本地信息来决定何时创建/销毁线程。如MSDN 上的 Patterns and Practices 文章所述

资源管理器是跨一个进程​​工作的单例。它不跨多个操作系统进程协调处理器资源。如果您的应用程序使用多个并发进程,您可能需要降低每个进程的并发级别以获得最佳效率。

如果您愿意接受复杂性,您可以实现自定义调度程序/资源管理器来获取简单的系统级性能读数(例如使用 PDH 函数)来实现您想要的。

于 2015-01-24T21:25:56.493 回答