我们正在使用OpenMP(libgomp)来加速多线程Qt应用程序中的某些计算。并行OpenMP部分位于两个不同的线程中,但实际上它们从不并行执行。我们在这种情况下观察到的是2N(其中N = OMP_THREAD_LIMIT
)omp线程被启动,显然每个线程都与另一个线程相互干扰。计算时间非常长,而处理器负载很低。设置OMP_WAIT_POLICY
几乎没有任何影响。
我们还尝试将所有omp部分移动到一个线程(从架构的角度来看,这对我们来说不是一个好的解决方案)。在这种情况下,总体计算时间会下降并且处理器已完全加载,但前提是OMP_WAIT_POLICY
设置为ACTIVE
。当OMP_WAIT_POLICY == PASSIVE
时,计算时间仍然很短,处理器空闲时间为50%。
奇怪的是,当我们在单个线程中使用omp时,使用omp并行化的第一个循环(在一系列omp计算中)与多线程情况相比执行速度慢10倍。
更新:我们的问题是:
a)在不同线程的上下文中使用omp时,有没有办法重用openmp线程。
b)为什么用OMP_WAIT_POLICY == PASSIVE
执行会减慢一切。唤醒线程需要这么长时间吗?
c)对于第一个并行块如此慢的现象(即使在活动模式下等待),是否有任何合理的解释
Upd2:请注意,该问题可能与GNU OMP实施有关。 icc没有它。
答案 0 :(得分:1)
尝试使用omp_set_num_threads(1)
和omp_set_num_threads(cpucount)
使用(1)
的此调用应该停止所有openmp工作线程,并且使用(cpu_num)调用将重新启动它们。
因此,在程序开始时,运行omp_set_num_threads(1)
。
在omp-parallelized区域之前,你可以使用WAIT_POLICY=active
启动omp线程,并且在此之前它们不会消耗cpu。
在omp并行区域之后,您可以再次停止线程。
omp_set_num_threads(cpucount)
调用非常慢,比使用wait_policy = passive唤醒线程要慢。这可能是(c)的原因 - 如果你的libgomp仅在第一个并行区域启动线程。