[英]parallelize nested loop in OpenMP and do inner loop with more thread
我有这种嵌套循环:我想知道如何以最佳形式并行化它,其中:
第二和第三for
也是第五和第六for
在同一时间运行
第一和第四for
串行
如果我有24个内核,并希望为螺纹16之间划分外,并利用它们的其余部分执行内for
他们,例如执行第二次for
8线程不是只有一个线程,我该怎么办?
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();
}
}
}
关于并行性介绍,通常会说越粗糙的级别越好,因此,如果您可以在可以扩展的粗糙级别添加并行指令,那么为什么还要添加嵌套并行性呢?
因此,根据可以同时运行的内容,我将这样编写main:
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可以完成工作。 遵循该逻辑进行嵌套循环。
但这不是我推荐的解决方案!
除了已经说过的内容,您可能还想显式启用嵌套并行性。 可以通过在运行时调用库或使用环境变量(对于OpenMP)来实现。
有关更多信息,请查看此Oracle Docs 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.