我正在查看一些使用 OpenMP 的代码,尽管我对它不太熟悉。(代码也不是 OpenMP。)
在针对它运行分析器时,我看到该程序据称在“OMP 隐式屏障”函数中花费了大约 20% 的挂钟时间。
这是 OpenMP 的典型特征,还是(可能)意味着工作负载在线程之间分布不均?
谢谢
我正在查看一些使用 OpenMP 的代码,尽管我对它不太熟悉。(代码也不是 OpenMP。)
在针对它运行分析器时,我看到该程序据称在“OMP 隐式屏障”函数中花费了大约 20% 的挂钟时间。
这是 OpenMP 的典型特征,还是(可能)意味着工作负载在线程之间分布不均?
谢谢
大多数 OpenMP 结构的末尾都有隐式障碍,例如for
(在 C/C++ 中)或do
(在 Fortran 中),sections
并且single
(但是,在结构的末尾没有障碍master
)。如果算法允许不同线程在工作共享指令之后不同步运行,则该nowait
子句可用于禁用这些隐式屏障。另一个隐式屏障位于每个并行区域的末尾,作为 fork/join 执行模型的一部分。
您已经正确猜到,隐式障碍等待时间的高百分比通常意味着工作共享远非最佳。可能存在(很多)大型single
结构,也可能存在并行循环(for
/do
结构),每次迭代的执行时间不同。如果不平衡来自每次迭代中计算时间不同的循环(典型示例是绘制 Mandelbrot 集),则可以将循环调度更改为dynamic
使用schedule(dynamic,chunk)
子句,其中chunk
是块大小 (>= 1)。块大小越小,负载平衡越好,但动态循环调度程序的开销会更高。块大小越大,开销越低,但会出现更多的负载不平衡。最佳值通常取决于问题的类型和硬件,因此必须调整该值才能在执行代码的特定系统上获得最佳性能。