【问题标题】:Parallelizing a for loop in Visual Studio 2010 (OpenMP)在 Visual Studio 2010 (OpenMP) 中并行化 for 循环
【发布时间】:2012-08-20 21:53:40
【问题描述】:

我最近阅读了有关 OpenMP 的内容,并试图在我的程序中并行化一些现有的 for 循环以加快速度。但是,由于某种原因,我似乎将垃圾数据写入文件。我的意思是我没有将点 1、2、3、4 等写入我的文件,我有点 1、4、7、8 等。我怀疑这是因为我没有跟踪线程,它只会导致竞争条件?

我一直在尽可能多地阅读有关 OpenMP 的内容,因为执行多线程编程似乎是一个很好的抽象。我将不胜感激任何指针,以了解我可能做错了什么。

这是我迄今为止一直在尝试做的事情(只有相关的代码):

#include <omp.h>

pixelIncrement = Image.rowinc/2;

#pragma omp parallel for
for (int i = 0; i < Image.nrows; i++ )
   {
      int k =0;
      row     = Image.data + i * pixelIncrement;

      #pragma omp parallel for
      for (int j = 0; j < Image.ncols; j++)
      {
          k++; 
          disparityThresholdValue = row[j];  
                 // Don't want to save certain points
             if ( disparityThresholdValue < threshHold)
             {       
                // Get the data points
                x = (int)Image.x[k]; 
                y = (int)Image.y[k]; 
                z = (int)Image.z[k]; 
                grayValue= (int)Image.gray[k];      

                cloudObject->points[k].x = x;
                cloudObject->points[k].y = y;
                cloudObject->points[k].z = z;
                cloudObject->points[k].grayValue = grayValue;

        fprintf( cloudPointsFile, "%f %f %f %d\n", x, y, z, grayValue);
             }
      }
   }

   fclose( pointFile );

我确实在我的编译器设置中启用了 OpenMP(C/C++ -> 语言 -> Open MP 支持 (/openmp)。

关于可能是什么问题的任何建议?我在 Windows XP 32 位上使用四核处理器。

【问题讨论】:

  • 似乎您想在标题中添加“OpenMP”。
  • #omp atomic 放在fprintf 行的上方。您仍然无法以正确的顺序获取数据,但至少所有内容都应该在文件中。
  • Hristo,请您详细说明“至少所有内容都应该在文件中”是什么意思。 ?
  • 我的意思是 fprintf 不能保证是线程安全的,但在您的情况下,问题是在并行区域之外定义的所有变量都是默认共享的,您遇到了麻烦比赛条件。

标签: c multithreading visual-studio-2010 for-loop openmp


【解决方案1】:

是否所有点都写入文件,但不是按顺序写入,还是实际点数据混乱?

第一种情况在并行编程中是预期的——一旦你并排执行某些事情,你将无法保证顺序,除非你同步访问(此时你可以省略并行化,因为它变成了有效的线性) .如果您需要依赖顺序,您可以并行化任何计算,但需要将其写在一个线程中。

如果点本身搞砸了,请检查变量的声明位置以及多个线程是否正在访问相同的变量。

【讨论】:

  • Femaref:实际点数据混乱。我理解同步时性能损失的意思。 #omp atomic 标签这样做对吗?您能否详细说明如何限制线程不访问相同的变量?我已经编辑了我的帖子以反映我必须做出的改变才能让它编译,我认为这是因为我如何定义我的 int k?由于某种原因,我似乎无法在 for 循环中成功定义 2 个整数。我真的很想为 (i = 0, k = 0; i
  • 如果我在 for 循环之外实例化变量,我得到的错误是:“OpenMP 'for' 语句格式不正确”
【解决方案2】:

这里有几个问题:

#pragma omp parallel for
for (int i = 0; i < Image.nrows; i++ )
   {
      int k =0;
      row     = Image.data + i * pixelIncrement;

      #pragma omp parallel for
      for (int j = 0; j < Image.ncols; j++)
      {
          k++; 

不需要内部的parallel for。外部循环应该包含足够的工作来保持所有核心都处于忙碌状态。

此外,对于内部循环,k 是一个共享变量,并以非原子方式递增。 xyz 也在内部循环线程之间共享并“随机”覆盖。删除内部指令,看看它是怎么回事。

【讨论】:

  • 同意 - 尝试并行化内部循环以及外部循环可能会导致问题。此外,您还需要明确声明哪些变量是私有变量,例如 jkrowxyzgrayValue,哪些是共享变量 - @ 987654335@、ImagecloudObjectcloudPointsFile。请参阅computing.llnl.gov/tutorials/openMP/#Combined 中的示例
  • 感谢 Tudor,但我仍然收到损坏的条目。我认为正如布赖恩建议的那样,我需要仔细查看并控制所有正在传递的变量......
【解决方案3】:

当你有一个带有嵌套循环的循环时,不需要第二个 omp pragma。 它已经将第一个循环并行化。请记住,这仅在必须按顺序执行第二个循环时才有效。您有一个顺序递增,因此您不能以随机顺序执行第二个循环。 OMP pragma 是并行化代码的一种非常简单和酷炫的方法,但不要过多地使用它们!

更多细节在这里 -> Parallel Loops with OpenMP

【讨论】:

    猜你喜欢
    • 2016-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    • 1970-01-01
    相关资源
    最近更新 更多