我有一個程序從不同的攝像機獲取原始數據流並將其寫入磁盤。程序運行這些記錄約2分鐘,然後用另一個程序處理幀。在C++中快速寫入很多大文件
每個原始幀都是2MB,幀速率是30fps(即數據速率約爲60MB/s),我正在寫入一個可以輕鬆處理持續> 150MB/s的SSD(通過複製4000 2MB來自另一個磁盤的文件需要38秒,Process Explorer顯示不變的IO活動)。
我的問題是,偶爾會調用fopen()
,fwrite()
和fclose()
攤位長達5秒,這意味着該幀的300MB建立在內存中作爲備份日誌,並經過幾次這些延遲的,我打的4GB的限制一個32位的進程。 (當延遲發生時,處理資源管理器示出了在IO活動間隙)
有運行在循環調用此函數爲每一個新幀,其被添加到隊列中的線程:
writeFrame(char* data, size_t dataSize, char* filepath)
{
// Time block 2
FILE* pFile = NULL;
fopen(&pFile, filepath, "wb");
// End Time block 2
// Time block 3
fwrite(data,1,dataSize,pFile);
// End Time block 3
// Time block 4
fclose(pFile);
// End Time block 4
}
(有錯誤檢查也在實際的代碼中,但它對這個問題沒有任何影響) 我正在記錄每個塊所花費的時間以及運行該函數所花費的總時間,並且我得到的結果大部分時間都是像這樣:(times in ms)
TotalT,5, FOpenT,1, FWriteT,2, FCloseT,2
TotalT,4, FOpenT,1, FWriteT,1, FCloseT,2
TotalT,5, FOpenT,1, FWriteT,2, FCloseT,2
即。 〜5ms運行整個功能,〜1ms打開文件,〜2ms調用寫入,〜2ms關閉文件。
偶爾但是(在每50幀平均約1%,但有時也可以是幾千幀的發生這個問題之間),我得到它接管4000ms幀:
TotalT,4032, FOpenT,4023, FWriteT,6, FCloseT,3
和
TotalT,1533, FOpenT,1, FWriteT,2, FCloseT,1530
所有的幀是相同的大小和它從來沒有fwrite
這需要額外的時間,總是fopen
或fclose
沒有其他進程正在讀取/寫入此SSD(通過進程監視器確認)。
有誰知道什麼可能導致此問題和/或任何避免/緩解此問題的方式?
每個幀都被寫入一個單獨的文件?也許你可以將一組幀寫入單個文件,並有一個單獨的線程進行後處理,以便將之後的N個幀和段分割成單獨的文件(以緩解視頻處理線程中的fopen/fclose調用)。這將允許您的writeFrame func運行得更快,而不會減慢視頻捕獲過程。 – spartygw
考慮檢查'fopen'和'fclose'實際上是否打開和關閉,同時檢查有多少個線程正在運行,這可能是您正在達到最大線程數量。 –
你沒有提到在SSD上使用的平臺或文件系統類型。如果是Windows,這將是一個使用異步寫入的好地方。 – Dan