2010-05-26 37 views
10

我在各种情况下运行我的代码,导致我认为是奇怪的行为。我的测试是使用HT的双核英特尔至强处理器。OpenMP num_threads(1)执行速度快于无OpenMP

否的OpenMP '的#pragma' 语句,总运行时间=507秒

对于OpenMP '的#pragma' 语句中指定1个芯,总运行时间=117秒

对于OpenMP“的#pragma '语句中指定2芯,总运行时间=150秒

对于OpenMP‘的#pragma’语句中指定3芯,总运行时间=157秒

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

我猜我不明白为什么注释掉我的openmp行会导致程序在1线程之间变慢,而没有使用openmp和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(引导)”行,我的结果不一致。

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

我想我还没有找到一个足够好的描述什么时间表(指导)为我做的,我明白,它试图分裂循环,使最耗时的迭代首先发生,这应该有一个效果一个线程等待其他人完成迭代的最少时间。

似乎对于我的〜900迭代循环,当我使用schedule(引导)时,我只处理〜200次迭代,其中没有计划(指导),我正在处理所有900次迭代。有什么想法吗?

+0

程序是否仍然产生正确的结果?也许你在编译器OpenMP实现中发现了一个错误。 – 2010-05-26 17:57:27

+0

尝试删除'schedule(引导)' – Jacob 2010-05-26 18:26:41

+0

您确定在每种情况下都使用了相同的编译器标志(尤其是优化标志)吗? – KeithB 2010-05-26 18:27:13

回答

7

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

我认为,当您将线程数设置为一个(1)时,OpenMP只是对实施该循环的OpenMP过程执行过程调用,因此开销很小,性能基本上与非OpenMP案件。

否则,我认为OpenMP的设置了一些信号灯,并等待“工人”线程醒来,同步它们对数据结构的访问,告诉他们什么环路参数设置,然后调用该做的工作常规,当他们完成大量的工作,他们再次发出主线程信号。这种同步必须发生在一个线程所做的每个工作块上,同步成本并不是微不足道的。

使用静态调度选项可以帮助减少调度/同步开销,尤其是当循环迭代的数量是相对于核的数量大。

+0

+1关于'STATIC'的好消息 – 2011-10-24 13:15:18