我在各种情况下运行我的代码,这导致我认为是奇怪的行为。我的测试是在带有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次迭代。有什么想法吗?
答案 0 :(得分:8)
OpenMP具有显着的同步开销。我发现,除非你有一个真正的大循环,它做了很多工作,并且没有循环内同步,否则通常不值得使用OpenMP。
我认为当你将线程数设置为一(1)时,OpenMP只是对实现循环的OpenMP过程进行过程调用,因此开销很小,性能基本上与非OpenMP情况相同。
否则,我认为OpenMP设置了一些信号量,等待“工作”线程唤醒,同步它们对数据结构的访问,告诉它们要设置什么循环参数,然后调用执行工作的例程,以及何时完成大量的工作,他们再次发出主线程的信号。这种同步必须发生在一个线程所做的每一块工作中,同步成本并不重要。
使用STATIC调度选项有助于减少调度/同步开销,尤其是在循环迭代次数相对于内核数量较大的情况下。