5

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

我不明白的是如何在 OpenMP 中获取私有变量。众所周知,fstream 的对象是不可复制的,直观地说,这使我无法将其用作私有对象。所以文件的阅读器是共享的。

后来我遇到了一些问题,我想尝试将 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)
{
...
}

谢谢你。

4

1 回答 1

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;
}

这是预期的输出:

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 支持?

于 2012-06-12T18:25:34.933 回答