2016-09-26 76 views
0

該問題主要涉及在大型(> 20GB)數據文件上計算一些函數,void lineProcess(string, string&, int[]),計算相當沉重,也很大程度上取決於輸入行的長度和數組參數引入的一些隨機性,所以我已經平均時間在幾次測試運行。第一個參數是文件的第一行,第二個是字符串的地址,所以結果可以輸出。輸出的總大小是3MB。沒有要求第k行輸入和輸出對應。除了文件io,它聽起來非常適合並行化,所以這裏是它的代碼。使用C++ OpenMP和文件io進行Parreleization。性能問題

void foo(const int param[]) { 
    // process some stuff ... 
    // create input stream fin, output stream fout from <iostream> 
    string result; 
    for (string line; getline(fin, line);) { 
#pragma omp parallel task firstPrivate(result) 
     lineProcess(line, result, param); 
     fout << result << endl; 
    } 
#pragma omp task wait 
    fin.close(); 
    fout.close(); 
} 

我已經跑了幾次,一臺筆記本電腦(酷睿i7四核,應該支持8個進程具有超線程),似乎沒有要多觀察加快。串行線程(即上述減去指令)平均約2800秒/行和平行約2000秒/行。我的目標是約600秒/線。我認爲問題的一部分可能是openMP實現,使用任務和taskwait,但是因爲我不知道文件中的行數,我看不到一個簡單的方法來使用#pragma omp for
理想情況下,我正在嘗試讀入和結果之一的線路緩衝區,並且處理所有線程,直到一個緩衝區幾乎爲空/滿,然後線程通過讀/寫磁盤交換來重新填充/清空它, m不確定這是否可以在OpenMP中完成,或者如果我可以做一個簡單的版本,只需要一個線程在讀/寫之間進行交換。 任何意見,爲什麼這不如預期的快速或改善表現的方法,將不勝感激。很顯然,讀取/寫入大量數據是有根本的限制,但是我知道行處理也佔用了很大一部分時間。

我發現這個問題使用非常相似的方法openmp - while loop for text file reading and using a pipeline第一個答案與我的代碼很好匹配,但第二個似乎是使用緩衝區,但我不知道如何完全適應它,或者如果它是值得的。

回答

0

您應該在for循環之前打開並行區域。這會生成一個運行多個線程的並行區域。在創建任務的時候,線程已經啓動,並且正在運行並準備好執行任務。

#pragma omp parallel 
{ 
#pragma omp single 
{ 
    for(...) 
    { 
    #pragma omp task 
    lineProcess(...) 
    fout ... 
    } 
} 
#pragma omp taskwait 
} 

這裏並行區域首先被打開,然後將其指出,對於僅由一個線程,這是產生任務procresed的follwoing,這反過來ARRE被多個線程工作。處理完所有行後(taskwait),正常代碼的執行可以繼續。

另外你還注意到只有lineProcess函數是一項任務。在生成任務之後(尚未完成或尚未完成),生成的線程將移至fout行並進行處理。你可以這樣解決它:

#pragma omp task 
{ 
lineProcess(...) 
fout ... 
fout.flush(); 
}