我有一个场景:
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
for (k = 0; k < x; k++)
{
val = 2*i + j + 4*k
if (val != 0)
{
for(t = 0; t < l; t++)
{
someFunction((i + t) + someFunction(j + t) + k*t)
}
}
}
}
}
考虑到这是块A,现在我的代码中有两个更相似的块。我想将它们并行放置,所以我使用了OpenMP pragma。但是我无法将其并行化,因为在这种情况下,我有点混淆了哪些变量将被共享和私有。如果内部循环中的函数调用是sum + = x之类的操作,那么我可以添加一个reduction子句。 一般来说,当我们有一个嵌套的for循环,然后另一个内部for循环执行主操作时,如何使用OpenMP并行化代码。 我尝试声明一个并行区域,然后简单地将pragma fors放在块之前,但我肯定错过了一点!
谢谢, 萨扬
答案 0 :(得分:1)
我比C更像是一个Fortran程序员,所以我对C风格的OpenMP知识很差,我会把语法留给你。
这里最简单的方法可能是(我稍后会对此进行限定)以简化最外层循环的并行化。默认情况下,OpenMP将变量i
视为私有,其余全部视为共享。这可能不是您想要的,您可能也希望将j
和k
以及t
设为私有。我怀疑你也希望val
私有。
我对你的循环嵌套底部的语句(即someFunction...
)感到有些困惑,它似乎根本没有返回任何值。是否有副作用?
因此,您不需要声明包含所有此代码的并行区域,并且您应该只能并行化最外层循环。如果您要对内部循环进行并行化,您可能会发现您的OpenMP安装忽略它们,产生的进程多于处理器,或者抱怨很痛苦。
我说你最简单的方法可能是将最外层的循环并行化,因为我已经对你的程序(片段)正在做什么做了一些假设。如果假设是错误的,您可能希望并行化其中一个内部循环。要检查的另一点是,您并行化的循环的执行次数远远大于您使用的线程数。你不希望在4个线程上拥有行程计数为7的OpenMP运行循环,负载平衡会很差。
答案 1 :(得分:0)
你是对的,最内层的陈述宁愿是someFunction((i + t)+ someFunction2(j + t)+ k * t)。