【问题标题】:Thread pools with OpenMP: overhead and changing the number of threads使用 OpenMP 的线程池:开销和更改线程数
【发布时间】:2019-10-03 03:26:50
【问题描述】:

我最近发现了thread pools 的概念。据我了解,GCC、ICC 和 MSVC 都使用 OpenMP 的线程池。我很想知道当我更改线程数时会发生什么?例如,假设默认线程数为 8。我创建了一个由 8 个线程组成的团队,然后在后面的部分中我会执行 4 个线程,然后我会回到 8 个线程。

#pragma omp parallel for
for(int i=0; i<n; i++)

#pragma omp parallel for num_threads(4)
for(int i=0; i<n; i++)

#pragma omp parallel for 
for(int i=0; i<n; i++)

这是我现在实际做的事情,因为我的部分代码在使用超线程时会得到更差的结果,所以我将线程数降低到物理内核数(仅针对那部分代码)。如果我反其道而行之(4 个线程,然后是 8 个线程,然后是 4 个线程)呢?

每次更改线程数时是否必须重新创建线程池?如果不是,添加或删除线程是否会导致任何重大开销?

线程池的开销是多少,即每个线程有多少工作量进入池?

【问题讨论】:

  • libgomp 在需要更多线程时产生额外的线程,但不会杀死已经产生的线程,而是让它们在停靠屏障中休眠。实际开销可以使用 EPCC 的OpenMP microbenchmarks 来衡量。

标签: multithreading threadpool openmp


【解决方案1】:

现在回答这个问题可能为时已晚。不过,我会这样做的。

当您从一开始就使用 8 个线程时,总共会创建 7 个线程,然后,包括您的主进程在内,您将拥有 8 个团队。因此,您的示例代码中的第一个循环将使用这个团队执行.因此,线程池有 8 个线程。在他们完成这个区域后,他们会进入睡眠直到醒来。

现在,当您到达具有 4 个线程的第二个并行区域时,线程池中只有 3 个线程被唤醒(3 个线程 + 您当前的主线程),其余线程仍处于睡眠模式。所以,有四个线程正在休眠。

然后,类似于第一个并行区域,所有线程将相互合并以执行第三个并行区域。


另一方面,如果您从 4 个线程开始,而第二个并行区域要求 8 个线程,那么 OpenMP 库将对此更改做出反应并创建 4 个额外线程来满足您的要求(8 个线程)。通常创建的线程在程序生命结束之前不会被抛出池。希望您将来可能需要它。这是大多数 OpenMP 库遵循的通用方法。这个想法背后的原因是创建新线程是一项昂贵的工作,这就是为什么他们试图避免它并尽可能推迟它。


希望这对您和未来的通勤者有所帮助。

【讨论】:

  • 这个答案只是 Hristo Iliev 在我的问题中的评论的更长答案。
猜你喜欢
  • 2012-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多