【发布时间】:2021-03-30 11:08:25
【问题描述】:
我正在尝试并行化一个程序的内部循环,该程序具有循环范围之外的数据依赖性(最小)。我遇到了一个问题,即残差计算发生在内 j 循环范围之外。如果 j 循环中包含“#pragma omp parallel”部分,即使由于 k 值太低而导致循环根本没有运行,代码也会出错。比如说 (1,2,3)。
for (i = 0; i < 10; i++)
{
#pragma omp parallel for shared(min) private (j, a, b, storer, arr) //
for (j = 0; j < k-4; j += 4)
{
mm_a = _mm_load_ps(&x[j]);
mm_b = _mm_load_ps(&y[j]);
mm_a = _mm_add_ps(mm_a, mm_b);
_mm_store_ps(storer, mm_a);
#pragma omp critical
{
if (storer[0] < min)
{
min = storer[0];
}
if (storer[1] < min)
{
min = storer[1];
}
//etc
}
}
do
{
#pragma omp critical
{
if (x[j]+y[j] < min)
{
min = x[j]+y[j];
}
}
}
} while (j++ < (k - 1));
round_min = min
}
【问题讨论】:
-
您能否更具体地说明您遇到了什么错误?这些是编译时错误还是您得到错误的结果?我的第一个想法是你在
min变量上有一个竞争条件,所以显而易见的解决方案是reduction(min:min)子句,你必须将它添加到parallel for指令中。 -
您应该只使用
_mm_min_ps来获得4 个最小值的向量,并在最后将其减少为一个元素(实际上,由于延迟,您需要多个寄存器),而不是所有分支。这可能有重复。 -
不过,您需要发布一个实际的minimal reproducible example(没有
//etccmets,也没有使用未声明的变量)。外循环实际上是做什么用的?x和y改变了吗?