使用OpenMP的线程池:开销和改变线程数量



我最近发现了线程池的概念。据我所知,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)?

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

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

现在回答这个问题可能有点晚了。然而,我要这么做。

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

现在,当你用4个线程到达第二个并行区域时,只有3个线程从你的线程池中被唤醒(3个线程+你当前的主线程),其余的线程仍然处于睡眠模式。因此,有四个线程处于睡眠状态。

然后,与第一个并行区域类似,所有线程将合并到第三个并行区域。


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


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

相关内容

  • 没有找到相关文章

最新更新