OpenMP是否复制私有对象?

时间:2012-06-12 15:34:21

标签: c++ parallel-processing openmp fstream noncopyable

我正在编写一个读取大文件(3x280 GB)的程序,并对文件中的数据进行拟合处理。并行化这样的程序非常方便,这可以通过OpenMP轻松完成。

我不明白的是在OpenMP中如何获取私有变量。众所周知,fstream的obejcts是一个不可复制的,并且不可思议地阻止我将它用作私有对象。所以该文件的读者是共享的。

我后来遇到了一些问题,我想过把fstream作为私人问题,然后猜猜是什么?有效!!!怎么可能这样?!如果对象是不可复制的,那么OpenMP如何为每个内核使用同一对象的不同副本?

这就是我的程序的样子:

fstream dataReaderX(Dirs[0].c_str(), ios::in | ios::binary);
fstream dataReaderY(Dirs[1].c_str(), ios::in | ios::binary);
fstream dataReaderZ(Dirs[2].c_str(), ios::in | ios::binary);
#pragma omp parallel num_threads(cpus_num) shared(...) private(...,dataReaderX,dataReaderY,dataReaderZ)
{
...
}

谢谢。

1 个答案:

答案 0 :(得分:6)

复制

firstprivate个变量,而不是private - 对于后者,调用默认构造函数:

第2.9.3.3节 - private条款:

  

新的列表项已初始化,或者具有未定义的初始值,就好像它是在没有初始化程序的情况下本地声明的那样。调用类型的不同私有变量的任何默认构造函数的顺序是未指定的。任何顺序   调用类类型的不同私有变量的C / C ++析构函数是未指定的。

这是一个简单的演示代码:

#include <fstream>
#include <stdio.h>
#include <omp.h>

int main (void)
{
   std::fstream reader("test.txt", std::ios::in);
   printf("Main thread: reader.is_open() = %d\n", reader.is_open());
   #pragma omp parallel private(reader)
   {
      printf("Thread %d: reader.is_open() = %d\n",
             omp_get_thread_num(), reader.is_open());
   }
   return 0;
}

这是预期的输出:

Main thread: reader.is_open() = 1
Thread 1: reader.is_open() = 0
Thread 0: reader.is_open() = 0
Thread 3: reader.is_open() = 0
Thread 2: reader.is_open() = 0

一个有趣的事情是,英特尔C ++编译器出现内部错误(断言失败) - 使用版本11.1,12.0和12.1进行了测试。另一方面,GNU C ++编译器遵循标准(上面的输出来自g++)。当使用firstprivate时,两个编译器都会抱怨,尽管英特尔C ++编译器再次出现内部错误。

这可能听起来很愚蠢,但您是否检查过您在使用的特定编译器中启用了OpenMP支持?