线程池 - CPU 用法?
Threadpool - CPU usage?
我正在开发 Windows C++ 应用程序。我们使用 boost 库。我的应用程序中有一个操作可以在多个线程上并行化为 运行。线程数每次取决于操作参数并且可以很大(比如 50 或 70)。我不想产生尽可能多的线程,因为这是应用程序对其他操作不响应的风险(因为这样做可能会占用所有处理器)。我怎样才能确保我没有造成我所描述的情况?线程池会有帮助吗?如果有的话如何?
您可以将 std::async
与默认启动策略一起使用。然而,这与线程池不同。
在 OpenMP 中,您可以设置固定数量的线程,然后使用 OpenMP task
s。不幸的是,C++11 中没有这样的选项。该标准表示,可以推迟选择函数是在新线程中异步调用还是在相应 std::future
对象上调用 wait
或 get
的线程中同步调用,但是,然后选择异步调用时,必须创建一个新线程。
只需创建一个线程池,例如我在这里发布的那个 boost thread throwing exception "thread_resource_error: resource temporarily unavailable"
这里还有两种风格c++ work queues with blocking(一种使用 Asio,一种仅使用 C++11)
现代硬件上的 70 个线程可以轻松处理 w/o 对系统性能的任何显着影响。线程创建时间、内存使用、调度和上下文切换开销可能是个问题,但我们不知道在您的特定情况下这是否是个问题。
如果创建 70 个线程不是一个选项,请考虑使用 OpenMP(所有主要编译器都支持),因为它是一个非常简单且通常非常有效的解决方案:
#pragma omp parallel for
for(int i = 1; i < 100; ++i)
{
do_task(i);
}
它在后台使用线程池。
如果由于某些原因 OpenMP 不可接受,您可以使用显式线程池。它可以是 "home-made" 线程池(不推荐),或者来自@sehe 的答案,或者由 OS 提供的线程池(正如@Hans Passant 在他的评论中提到的),或者来自第三个-party 库(例如英特尔线程构建模块)。
是的,线程池可以帮助提高响应能力,尽管默认情况下典型的线程池实现会创建线程数 == 逻辑 CPU 核心数。这意味着您的所有核心都可以忙于工作,这不一定是个问题。 Windows 使用抢占式多线程。这意味着它可以处理比 CPU 多得多的线程数并且仍然可以响应。
线程池可以 提供帮助,因为同时执行的任务不可能超过您拥有的逻辑CPU 核心数。线程池 可以 更高效,因为可以更好地使用缓存并减少上下文切换次数。或者因为可以使用相同的线程多次执行您的操作。确定了解您的表现。
我正在开发 Windows C++ 应用程序。我们使用 boost 库。我的应用程序中有一个操作可以在多个线程上并行化为 运行。线程数每次取决于操作参数并且可以很大(比如 50 或 70)。我不想产生尽可能多的线程,因为这是应用程序对其他操作不响应的风险(因为这样做可能会占用所有处理器)。我怎样才能确保我没有造成我所描述的情况?线程池会有帮助吗?如果有的话如何?
您可以将 std::async
与默认启动策略一起使用。然而,这与线程池不同。
在 OpenMP 中,您可以设置固定数量的线程,然后使用 OpenMP task
s。不幸的是,C++11 中没有这样的选项。该标准表示,可以推迟选择函数是在新线程中异步调用还是在相应 std::future
对象上调用 wait
或 get
的线程中同步调用,但是,然后选择异步调用时,必须创建一个新线程。
只需创建一个线程池,例如我在这里发布的那个 boost thread throwing exception "thread_resource_error: resource temporarily unavailable"
这里还有两种风格c++ work queues with blocking(一种使用 Asio,一种仅使用 C++11)
现代硬件上的 70 个线程可以轻松处理 w/o 对系统性能的任何显着影响。线程创建时间、内存使用、调度和上下文切换开销可能是个问题,但我们不知道在您的特定情况下这是否是个问题。
如果创建 70 个线程不是一个选项,请考虑使用 OpenMP(所有主要编译器都支持),因为它是一个非常简单且通常非常有效的解决方案:
#pragma omp parallel for
for(int i = 1; i < 100; ++i)
{
do_task(i);
}
它在后台使用线程池。
如果由于某些原因 OpenMP 不可接受,您可以使用显式线程池。它可以是 "home-made" 线程池(不推荐),或者来自@sehe 的答案,或者由 OS 提供的线程池(正如@Hans Passant 在他的评论中提到的),或者来自第三个-party 库(例如英特尔线程构建模块)。
是的,线程池可以帮助提高响应能力,尽管默认情况下典型的线程池实现会创建线程数 == 逻辑 CPU 核心数。这意味着您的所有核心都可以忙于工作,这不一定是个问题。 Windows 使用抢占式多线程。这意味着它可以处理比 CPU 多得多的线程数并且仍然可以响应。
线程池可以 提供帮助,因为同时执行的任务不可能超过您拥有的逻辑CPU 核心数。线程池 可以 更高效,因为可以更好地使用缓存并减少上下文切换次数。或者因为可以使用相同的线程多次执行您的操作。确定了解您的表现。