11

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

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

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

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

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

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

我想我不明白为什么注释掉我的 openmp 行会使程序在没有 openmp 的 1 个线程和有 openmp 的 1 个线程之间减慢这么多。

我要改变的只是:

//#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)”行,我的结果不一致。

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

我想我还没有找到足够好的描述 schedule(guided) 为我做了什么,我知道它试图拆分循环,以便首先发生最耗时的迭代,这应该产生最少的影响一个线程等待其他线程完成迭代的时间。

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

4

1 回答 1

8

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

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

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

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

于 2011-03-14T13:13:05.170 回答