OpenMP num_threads(1)的执行速度比没有OpenMP的速度快

时间:2010-05-26 17:41:09

标签: c++ c multithreading openmp

我在各种情况下运行我的代码,这导致我认为是奇怪的行为。我的测试是在带有HT的双核intel xeon处理器上进行的。

没有OpenMP'#pragma'语句,总运行时间= 507秒

使用OpenMP'#pragma'语句指定1个核心,总​​运行时间= 117秒

使用OpenMP'#pragma'语句指定2核,总运行时间= 150秒

使用OpenMP'#pragma'语句指定3个核心,总​​运行时间= 157秒

使用OpenMP'#pragma'语句指定4核,总运行时间= 144秒

我想我无法弄清楚为什么注释掉我的openmp行会使程序在没有openmp的1个线程和1个带有openmp的线程之间变慢。

我正在改变的是:

//#pragma omp parallel for shared(segs) private(i, j, p_hough) num_threads(1) schedule(guided)

and...

#pragma omp parallel for shared(segs) private(i, j, p_hough) num_threads(1,2,3,4) schedule(guided)

无论如何,如果有人知道为什么会这样,请告诉我!

感谢您的帮助,

布雷特

编辑:我将在这里解答一些评论

我正在使用num_threads(1),num_threads(2)等。

经过进一步调查后发现,根据代码中是否包含“schedule(guided)”行,我的结果不一致。

- 当我使用计划(指导)行时,无论线程数如何,我都会生成最快的解决方案。 - 当我使用默认调度程序时,我的结果显着更慢且值不同 - 通过增加线程不会获得计划(引导)改进 - 没有时间表(指导)我通过添加线程获得了改进

我想我没有找到足够好的时间表(指导)对我的描述,我明白它试图拆分循环,以便最先进行时间密集的迭代,这应该有效果一个线程等待其他线程完成迭代的最短时间。

看来,对于我的~900迭代循环,当我使用schedule(被引导)时,我只处理~200次迭代,其中没有时间表(被引导)我正在处理所有900次迭代。有什么想法吗?

1 个答案:

答案 0 :(得分:8)

OpenMP具有显着的同步开销。我发现,除非你有一个真正的大循环,它做了很多工作,并且没有循环内同步,否则通常不值得使用OpenMP。

我认为当你将线程数设置为一(1)时,OpenMP只是对实现循环的OpenMP过程进行过程调用,因此开销很小,性能基本上与非OpenMP情况相同。

否则,我认为OpenMP设置了一些信号量,等待“工作”线程唤醒,同步它们对数据结构的访问,告诉它们要设置什么循环参数,然后调用执行工作的例程,以及何时完成大量的工作,他们再次发出主线程的信号。这种同步必须发生在一个线程所做的每一块工作中,同步成本并不重要。

使用STATIC调度选项有助于减少调度/同步开销,尤其是在循环迭代次数相对于内核数量较大的情况下。