外循环上的OpenMP:如何在内循环后打印输出?

时间:2016-05-31 03:06:18

标签: c printf openmp

我有一个程序定义矩阵 Pixel ,一个函数 iBlend (我无法看到或改变),它在 Pixel 返回一个浮点数,实际上只包含以下内容:

float RowResult[columns];
#pragma omp parallel for
for (int i = 0; i < rows; i++) {
   float sum = 0;
   RowResult[0] = 0;
   for (int j = 1; j < columns; j++) {
       RowResult[j] = iBlend(Pixel[i],Pixel[j],RowResult[j-1]);
       sum += RowResult[j];
   }
   printf("Row %d scored a total of: %f\n", i, sum);
   if (sum > 100) {
      for (int j = 0; j < columns; j++) printf("%f,",RowResult[j]);
      printf("\n");
   }
}

这段代码通过一个矩阵,一次一行,用索引i和j做一些花式数学。

当然,当我尝试使用超过1个线程运行它时,这会导致乱码,因为线程以先到先得的方式调用printf。

我尝试在函数的第二部分添加一个简单的#pragma omp single(从第一个printf到第二个到最后一行创建一个块),但是我得到了关于无法嵌套的经典错误omp块:

> error: work-sharing region may not be closely nested inside of
> work-sharing, ‘critical’, ‘ordered’, ‘master’, explicit ‘task’ or
> ‘taskloop’ region
>    #pragma omp single 
>            ^~~

我想到了一些解决方案。首先是&#34;只需定义一个足够大的矩阵来保存所有答案,然后在最后用一个线程循环它们。&#34;但是这种方式实际上我的内存耗尽 - 事实证明只有几行真正被打印出来,所以在运行中这样做是非常必要的。我也无法改变输出的格式,尽管按哪种顺序打印哪一行并不重要,只要它按行打印并且像素按行顺序排列即可。

我想到的另一个解决方案是&#34;只需翻转两个循环并让omp循环穿过另一个方向的像素,然后当完成并行循环时,我就在单线程的土地上再次&#34!; - 但事实证明,行需要按顺序计算像素,因为它们带有依赖性(iBlend需要先前计算的结果)。

起初我认为这是一个简单的问题,所以也许我只是遗漏了一些明显的东西。我只想退出&#34;多线程&#34;我打印时的模式。也许类似于&#34;将这个结果添加到答案堆栈中(将堆栈添加为&#39;原子&#39;使用OpenMP?)&#34;然后&#34;如果我是主线程,到目前为止打印堆栈中的所有内容&#34;?但这实施起来很慢而且有点棘手。我确信这是一种更简单的方法。 ......对吧?

感谢您的帮助。

0 个答案:

没有答案