2010-04-23 50 views
2

我目前正在使用替換選擇和k路合併來處理涉及外部合併排序的項目。我用C++ [在Linux上運行]實現了該項目。它非常簡單,現在只處理固定大小的記錄。提高C++程序的I/O性能[外部合併排序]

對於閱讀&寫我使用(I/O)fstream類。執行該程序幾次後,我注意到

  • 對於大於4K(典型塊大小)的請求,I/O讀取塊。事實上,緩衝區大小超過4K會導致性能下降。
  • 輸出操作似乎不需要緩衝,linux似乎照顧緩衝輸出。所以我發出一個寫(記錄),而不是保持特殊的寫入緩衝區,然後使用write(records [])立即清除它們。

但是,應用程序的性能似乎不是很好。我怎麼能改善表現?我應該維護特殊的I/O線程來處理讀取塊或者是否存在提供此抽象的現有C++類?(類似於Java中的BufferedInputStream)

+2

簡介第一!對於大於最佳塊大小的性能,性能只會緩慢下降,因此可能不會成爲第一個問題。 – Potatoswatter 2010-04-23 01:49:05

+0

對於> 4096字節的緩衝區,它們是512的精確倍數嗎? – wallyk 2010-04-23 01:51:13

+0

4k的東西是有道理的。這通常是許多文件系統的本地塊大小,也是x86的本地頁面大小。 – 2010-04-23 03:53:51

回答

3

如此高性能的I/O最容易在mmap下完成。這爲內核提供了更多的自由來執行I/O併爲您的應用程序計劃CPU時間。例如,當您使用ifstream讀入1 MB時,內核只能在讀取所有數據時返回。但使用mmap()時,數據可以在可用時遞增返回。

但是,你應該明白這是怎麼發生的。僅僅因爲數據似乎在RAM中並不意味着您應該將其視爲隨機訪問。不要餵它到std::sort。這會觸及mmap的區域的隨機部分,導致頁面錯誤向左和向右移動。因此,您將導致繁重的磁盤尋求解決隨機頁面錯誤。相反,mmap()兩個輸入併合並它們。由於mmap命令將內核告訴內核將來需要的數據,因此內核將盡可能快地爲您提供數據,並且您的合併排序將在暫時無法使用數據時導致頁面錯誤(即暫停)。

+0

謝謝。我會嘗試mmap,很快就會收到結果! – Ajay 2010-04-24 08:23:09

1

與普通C I/O.事實上,它們「易於使用且適合不同情況」,但性能不足。在你的情況下,我會做的是切換到C風格的I/O,分析然後根據分析結果採取行動。