簡體   English   中英

使用OpenMP獲得完整,完整的輸出需要什么?

[英]What is needed to get complete, uncorrupted output with OpenMP?

我有一些在c ++ 11標准下編譯的代碼。 我有多個線程寫入cout。 我注意到在編寫多行時,有些情況下會缺少某些行(例如2000000中的1)。 我很驚訝地看到這一點,因為我的字符串(下面的outStr )對於每個線程都是本地的,並且在對stdout的寫操作中有一個關鍵部分。 我注意到沖洗河流時問題消失了。

#pragma omp critical(cout)
{
    cout << outStr;
    cout.flush();
}

這是預期的行為嗎? 真正困擾我的是,當我編寫相對較少的行數(<100000)時,我總是會看到輸出的預期行數。

總的來說,我對關鍵部分並不十分滿意,因為我在分析中注意到它引起了很多爭論。 我願意提出任何改善我的I / O的建議。

*編輯我給人的印象是,在c ++ 11下,只要我同步輸出(即使用關鍵部分時就不會出現交錯或丟失輸出),輸出就不會損壞,但是缺少的行似乎表明如果不刷新輸出就無法保證。

這里的許多問題源於沖洗流相當慢的事實。 因此,當一個線程進入關鍵部分時,他們會在其中停留相當長的時間。 當它們完成時,可能還有其他幾個線程在等待,因此這成為一個嚴重的瓶頸。

預防該問題的最明顯的方法可能是使流本身歸一個線程所有,並具有一個線程安全的隊列,該隊列需要將需要寫入該線程的事物。 如果您可以累積一個“大塊”數據以將該流放入一個字符串(或其他一些預定的數據結構)中,那么這很簡單。

記錄一下,雖然您最終可能想使用無鎖隊列,但是基於鎖的相當簡單,老式的隊列幾乎可以肯定會比您現在正在做的事情有很大的改進-插入一個字符串轉換為隊列是大幅度超過沖洗流更快(以納秒的范圍內,從而可能在幾微秒,其中沖洗是通常毫秒的數量級上)。

似乎std::cout.sync_with_stdio(false); 是罪魁禍首。 我沒想到這是問題,但是在我做了一個簡單的測試程序后我注意到了。 我曾嘗試使用該功能來加快I / O的速度,但事實證明這不是一個好主意。

看起來,盡管在關鍵部分,I / O流也不是線程安全的。 我也沒有在代碼中使用任何printf

根據文檔

此外,同步的C ++流保證是線程安全的(多個線程輸出的單個字符可能會交織,但不會發生數據爭用)

似乎由於某些原因,不同步緩沖區將決定以隨機間隔刷新。

刪除后,我實際上可以通過一個簡單的`cout << outStr;獲得一致的輸出。 無需沖洗的聲明。 另外,我仍在進行測試,看來我可能根本不需要關鍵部分。

暫無
暫無

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

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