簡體   English   中英

在OpenMP線程中降低性能

[英]fread slow performance in OpenMP threads

我使用Intel Xeon x2(24內核)和Windows Server 2008。
試圖並行化我的c ++程序。 這里的模板代碼:

vector< string > files;
vector< vector< float > > data; 
...
data.resize( files.size() ); 

#pragma omp parallel for 
for (int i=0; i<files.size(); i++) { // Files count is about 3000
    FILE *f = fopen(files[i].c_str(), "rb"); 

    // every file is about 40 mb
    data[i].resize(someSize);
    fread(&data[i][0], sizeof(float), someSize, f); 

    fclose(f);
    ...
    performCalculations();  
}

CPU使用率僅為0到5%。
當我插入而不是fread(&data [i] [0],sizeof(float),someSize,f)

for (int j=0; j<data.size(); j++) {
    data[i][j] = rand(); 
}

CPU使用率增加到100%。
我已經嘗試過使用fstream和WinApi ReadFile,但它沒有產生太大影響。

我究竟做錯了什么? 我不相信磁盤讀數會這么慢......

我不相信磁盤讀數會這么慢......

然后你最好開始相信。 與CPU相比,磁盤速度極慢。 並行I / O通常僅在您從多個源(如單獨的磁盤或網絡連接)讀取時才有幫助。 它可以很好地解決延遲問題,但不能解決帶寬問題。

嘗試一次性讀取所有數據,然后連續讀取,然后在並行循環中處理它。

磁盤讀數無法並行化*:您是否擁有1或24個CPU內核不會改變磁盤I / O吞吐量。

如果一個 performCalculations(); 調用比讀取其中一個 40 MB文件的內容要快,然后就不需要在多個CPU上並行化了。 您的程序執行受磁盤帶寬的限制。 你測量過這個嗎?

*:他們可以,但需要硬件。 就像在多個CPU上並行執行需要實際的多CPU硬件一樣,並行化磁盤I / O需要更多的磁盤I / O硬件。

如果您使用傳統的HDD,則不會有任何可見的加速,因為會有許多並發文件讀取。 HDD主要無法處理此類當前文件讀取。 這就是為什么你只有0-5%的CPU使用率,這意味着大多數並行循環只是等待文件操作。 (請注意,只要多個文件讀數位於不同的物理磁盤或盤片上,磁盤讀數就可以並行化。)

有幾個解決方案:

  1. 嘗試使用可以支持更好的隨機/並發訪問的SSD。
  2. 雖然在這個答案中解釋一切並不容易,但嘗試使用管道並行性 OpenMP不適合流水線操作,但TBB支持易於使用的管道模板。 Pipeline允許文件讀取步驟和其他計算步驟,因此您可以獲得不錯的加速。 當然,應該有足夠的計算。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM