我正在编写一个读取大文件(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)
{
...
}
谢谢。
答案 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支持?