我在各种情况下运行过我的代码,这导致了我认为奇怪的行为。我的测试是在具有 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/