2012-06-12 49 views
4

我在寫一個讀取大文件(3x280 GB)的程序,並對文件中的數據進行擬合過程。並行這樣一個程序非常方便,在OpenMP中很容易完成。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) 
{ 
... 
} 

謝謝。

回答

5

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++)。儘管英特爾C++編譯器再次發生內部錯誤,但兩個編譯器都會抱怨使用firstprivate

這可能聽起來很愚蠢,但是您是否檢查過您正在使用的特定編譯器中是否啓用了OpenMP支持?