c++ - OpenMP num_threads(1) 比没有 OpenMP 执行得更快

标签 c++ c multithreading openmp

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

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

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

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

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

使用指定 4 核的 OpenMP '#pragma' 语句,总运行时间 = 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(guided)”行不一致。

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

我想我还没有找到关于 schedule(guided) 对我的作用的足够好的描述,我确实理解它试图拆分循环以便最耗时的迭代首先发生,这应该会产生影响一个线程等待其他线程完成迭代的最短时间。

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

最佳答案

OpenMP 具有显着的同步开销。我发现,除非您有一个真正 的大循环来完成大量工作,并且没有循环内同步,否则通常不值得使用 OpenMP。

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

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

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

关于c++ - OpenMP num_threads(1) 比没有 OpenMP 执行得更快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2915390/

相关文章:

java - 什么是 JVM 可以创建的线程的阈值限制数

multithreading - OpenMP 和shared_ptr

c++ - boost 链接错误

c++ - 对类的 undefined reference

c - 尝试通过传递 ip (getnameinfo) 打印名称时出现段错误

通过 C 书计算字符数

java - java中的Timeline和Thread有什么区别

c++ - for 语句头的 init-statement 中不允许使用逗号运算符的表达式

c++ - 各种 boost ublas 稀疏 vector 之间有什么区别?

协程:如何判断 Windows Fiber 是否已完成执行?