在另一个并行循环中调用函数时,函数中的“pragma omp parallel for”无效
Posted
技术标签:
【中文标题】在另一个并行循环中调用函数时,函数中的“pragma omp parallel for”无效【英文标题】:"pragma omp parallel for" in function not effective when function is called within another parallel loop 【发布时间】:2019-10-10 11:16:14 【问题描述】:在并行化的“for”循环中,我正在调用一个函数,该函数又包含一个昂贵的计算,我想与剩余的 CPU 并行化。但是,我的内部“parallel for”指令被忽略了。
这是用于图像处理管道。相机有 4 个探测器,例如100 张图片。我想为每个检测器计算 100 个输入图像的中位数。因此,我的外循环为 4 个检测器使用 4 个线程,我想使用剩余的 CPU 来并行化内循环中的中值计算。
int main()
// OUTER LOOP over various detectors
# pragma omp parallel for
for (int det=0; det<4; ++det)
// some serial work
calculate_median(det);
void calculate_median(int det)
// some serial work
#pragma omp parallel for num_threads(available_additional_threads)
for (int pixel =0; pixel < numpixels; ++pixel)
// create a stack of pixels from the 100 input images
// calculate median of stack
// more serial work
我根据摄像头的探测器数量和用户机器上的 CPU 数量来计算额外的可用线程。像这样,运行的线程永远不会多于 CPU。
我观察到内部的“omp parallel for”被忽略了,即无论“available_additional_threads”的值如何,我都只得到一个线程。 但是,如果我确实将外部循环设置为单个线程,那么内部并行化将按预期工作。这真的让我很困惑。 非常感谢您提供任何额外的见解!
更新/解决方案: 设置 'omp_set_nested(true)' 启用内循环并行化。
【问题讨论】:
调查omp_set_nested
。默认情况下(没有嵌套并行),您描述的行为正是指定 OMP 的工作方式。
亲爱的麦克斯,就是这样!设置 omp_set_nested(true) 解决了我的问题。现在,我的一个内部变量出现了段错误,我(还)不明白。但我问的主要问题是回答/。非常感谢!
【参考方案1】:
您可以使用编译器支持 OpenMP 3.0 的 collapse 子句
#pragma omp parallel for collapse(2)
for (int x = 0; x < x_max; ++x)
for (int y = 0; y < y_max; ++y)
//parallelize this code here
//IMPORTANT: no code in here
,但是这个接缝在这里不适用,因为你必须做一些连续的工作。
我的经验是,嵌套循环的性能比一个并行循环差,后者很好地进行了面板化。
通常,只并行化外循环是个好主意。由于您的外循环只有 4 次迭代,我认为仅将 OMP 用于内循环是合理的。调度器可以更好地处理负载不平衡。
牢记性能重构的黄金法则:衡量。
我建议您使用诸如英特尔的 Vtune 放大器之类的工具来衡量您的性能,以及嵌套循环是否真的可以帮助您。
【讨论】:
亲爱的 schorsch312,正如您所说,“折叠”条款对我的问题没有帮助。此外,相机设置差异很大。其中一些有多达 72 个检测器,比 CPU 多得多,因此对于我的内部循环,我从不请求超过一个线程。系统已满载。我想要优化的是 CPU 比检测器多的情况。内部计算非常昂贵,无需担心并行化开销。 @MischaSchirmer,但numpixels
应该总是比 CPU 的数量大,对吧?如果这是真的,即使你只并行化内部循环,你也会占用所有处理器。
这就是为什么我有 num_threads() 子句,将 CPU 的数量限制为内部循环实际可用的数量。
与其尝试使用嵌套并行,不如使用 taskloop,它可以为您提供负载平衡并跨线程共享层次结构中所有级别的工作。以上是关于在另一个并行循环中调用函数时,函数中的“pragma omp parallel for”无效的主要内容,如果未能解决你的问题,请参考以下文章