OpenMP是否复制私有对象?

The*_*ist 5 c++ parallel-processing fstream openmp noncopyable

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

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

我后来遇到了一些问题,我想把fstreams作为私有,...并猜猜是什么?有效!!!怎么可能这样?!如果对象是不可复制的,那么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)
{
...
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

Hri*_*iev 7

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;
}
Run Code Online (Sandbox Code Playgroud)

以下是预期的输出:

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
Run Code Online (Sandbox Code Playgroud)

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

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