在 OpenMP 中并行化嵌套循环并使用更多线程执行内部循环
Posted
技术标签:
【中文标题】在 OpenMP 中并行化嵌套循环并使用更多线程执行内部循环【英文标题】:parallelize nested loop in OpenMP and do inner loop with more thread 【发布时间】:2013-07-22 23:07:46 【问题描述】:我有这种嵌套循环:我想知道如何以最佳形式并行化它:
第二个和第三个for
以及第五个和第六个for
运行相同
时间
第一个和第四个for
串行
如果我有 24 个核心,并且想在 16 个线程之间划分外部并使用其余的与它们一起执行内部 for
,例如使用 8 个线程执行第二个 for
而不仅仅是一个线程,我该怎么办?
void main()
//first_for
for(int y=0; y< height; y++)
//second_for
for(int x=0; x< width-1; x++)
func1();
//third_for
for(int x=0; x< width-1; x++)
func2();
//fourth_for
for(int x=0; x<width; x++)
//fifth_for
for(int y=0; y< height-1; y++)
func3();
//sixth_for
for(int y=0; y< height-1; y++)
func4();
【问题讨论】:
但是第一个和第四个是否与其他 4 个同时运行? 第一个 first_for 和之后的第四个_for ? OpenMP 中嵌套循环的最佳处理是什么? 我认为您误解了 OpenMP 的嵌套并行性。如果您在 16 个线程上运行外部循环并在该范围内请求 8 个线程,您将获得(假设您的实现支持嵌套并行)16*8==128
线程总数;也就是说,外 16 根螺纹中的每根都有 8 根内螺纹。在 24 核机器上,这可能总是一个坏主意,因为线程争夺对处理器内核的访问权限,因为它们每个都会破坏其他缓存,等等。
是的@Mark你是对的Mark,以及在for中使用sections指令如何并行执行两个内部for,我注意到你的观点,但我想同时执行这两个for同一时间
【参考方案1】:
除了已经说过的内容之外,您可能还想显式启用嵌套并行性。可以通过运行时的库调用或环境变量(对于 OpenMP)来执行此操作。
欲了解更多信息,请查看此Oracle Docs。
【讨论】:
【参考方案2】:关于并行性介绍,通常说越粗的级别越好,所以如果您可以在扩展良好的粗略级别添加并行指令,为什么还要添加嵌套并行?
所以基于可以同时运行的内容,我会这样编写主要内容:
int main()
//first_for
#pragma parallel for
for(int y=0; y< height; y++)
//second_for and third_for
for(int x=0; x< width-1; x++)
func1();
func2();
//fourth_for
#pragma parallel for
for(int x=0; x<width; x++)
//fifth_for and //sixth_for
for(int y=0; y< height-1; y++)
func3();
func4();
return 0;
我们通过合并 2 个内部循环来增加每行和每列的工作量
我们添加了 openMP 指令以根据您的核心数量将该计算循环拆分为更小的块。
查看是否可以反转第一个循环,因为取决于您在内部执行的操作以及“图像”在内存中的映射方式,首先处理列可能会导致大量缓存错误....
编辑
您可以启用嵌套并行性,但它走错了路,过多的循环和线程访问不同的内存块只会降低性能,您还将拥有一个为 24 核设计的解决方案,可能无法与 32 扩展, 48 核等...但如果您坚持必须设置环境变量或调用 openMP 函数:
call omp_set_nested()
or
set OMP_NESTED=TRUE|FALSE
在您的***循环上添加一个 openMP 子句以指定您想要的块大小以便只有 X 线程。
int chunckSize = height / X;
#pragma parallel for schedule ( static , chunckSize)
openMP 线程团队应该由 24 个线程组成,但这样做只有 X 有工作要做。遵循嵌套循环的逻辑。
但这不是我推荐的解决方案!
【讨论】:
我想知道这是最好的形式吗?这个问题呢?如果我有 24 个内核并且想在 16 个线程之间划分外层并使用其余部分与它们一起执行内层,例如使用 8 个线程执行第二个而不是一个线程,我该怎么办? 我编辑了我的答案,但是你走的方式会导致奇怪的行为,更多的同步点(加入)等等......,以上是关于在 OpenMP 中并行化嵌套循环并使用更多线程执行内部循环的主要内容,如果未能解决你的问题,请参考以下文章