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

Bre*_*ett 10 c c++ multithreading openmp

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

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

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

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

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

使用指定4核的OpenMP'#pragma'语句,总运行时间= 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)
Run Code Online (Sandbox Code Playgroud)

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

谢谢你的帮助,

布雷特

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

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

经过进一步调查,结果表明,根据代码中是否包含"schedule(guided)"行,我的结果不一致.

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

我想我还没有找到一个足够好的描述(导引)对我做什么,我明白它试图分割循环,以便最先进行时间密集的迭代,这应该具有最小的影响一个线程等待其他线程完成迭代的时间.

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

小智 8

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

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

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

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