簡體   English   中英

何時為I / O(C ++)構建自己的緩沖系統?

[英]When to build your own buffer system for I/O (C++)?

我必須處理非常大的文本文件(2 GB),必須逐行讀/寫它們。 使用ofstream編寫2300萬行非常慢,所以在開始時,我試圖加快在內存緩沖區(例如256 MB或512 MB)中寫入大塊行的過程,然后將緩沖區寫入文件。 這不起作用,性能或多或少相同。 我在閱讀文件時遇到同樣的問題。 我知道I / O操作是由STL I / O系統緩沖的,這也取決於磁盤調度程序策略(由操作系統管理,在我的情況下是Linux)。

有關如何提高性能的任何想法?

PS:我一直在考慮使用后台子進程(或線程)來讀取/寫入數據塊,而程序正在處理數據但我不知道(主要是在子進程的情況下)這是否值得。

2GB的文件非常大,您需要了解可能充當瓶頸的所有可能區域:

  • 硬盤本身
  • 硬盤接口(IDE / SATA / RAID / USB?)
  • 操作系統/文件系統
  • C / C ++庫
  • 你的代碼

我首先做一些測量:

  • 您的代碼讀取/寫入2GB文件需要多長時間,
  • dd ”命令讀取和寫入磁盤的速度有多快? 例...

    dd if=/dev/zero bs=1024 count=2000000 of=file_2GB

  • 使用大的fwrite()/ fread()調用寫/讀需要多長時間

假設您的磁盤能夠以大約40Mb / s的速度進行讀/寫(這可能是一個真實的數字),您的2GB文件運行速度不會超過50秒。

它實際需要多長時間?

嗨Roddy,使用帶有1.1 GB文件和大緩沖區(128,255或512 MB)的fstream讀取方法,它需要大約43-48秒,並且使用fstream getline(逐行)是相同的。 cp需要將近2分鍾來復制文件。

在這種情況下,你的硬件綁定。 cp必須讀寫,並且會在瘋狂的情況下在磁盤表面上來回尋找。 所以它(如你所見)將比簡單的'讀'案例差兩倍多。

為了提高速度,我首先嘗試的是更快的硬盤驅動器或SSD。

你還沒說過磁盤接口是什么? SATA幾乎是最簡單/最快的選擇。 另外(顯而易見的是,這......)確保磁盤實際上在您的代碼運行的同一台機器上,否則您將受到網絡限制......

我還建議使用內存映射文件但是如果你要使用boost我認為boost :: iostreams :: mapped_file比boost :: interprocess更好。

也許你應該研究內存映射文件。

在這個庫中檢查它們: Boost.Interprocess

只是一個想法,但避免使用std :: endl,因為這將在緩沖區滿之前強制刷新。 使用'\\ n'代替換行符。

不要使用new來分配緩沖區:

嘗試:std :: vector <>

unsigned int      buffer_size = 64 * 1024 * 1024; // 64 MB for instance.
std::vector<char> data_buffer(buffer_size);
_file->read(&data_buffer[0], buffer_size);

另請閱讀有關在標識符名稱中使用下划線的文章 注意你的代碼沒問題但是。

使用getline()可能效率很低,因為當從流緩沖區向數據附加數據時,字符串緩沖區可能需要重新調整大小幾次。 您可以通過預先調整字符串大小來提高效率:

您還可以將iostreams緩沖區的大小設置為非常大或NULL(對於無緩沖)

// Unbuffered Accesses:
fstream file;
file.rdbuf()->pubsetbuf(NULL,0);
file.open("PLOP");

// Larger Buffer
std::vector<char>  buffer(64 * 1024 * 1024);
fstream            file;
file.rdbuf()->pubsetbuf(&buffer[0],buffer.size());
file.open("PLOP");

std::string   line;
line.reserve(64 * 1024 * 1024);

while(getline(file,line))
{
    // Do Stuff.
}

如果你要自己緩沖文件,那么我建議使用無緩沖的I / O進行一些測試(在你已經開啟的文件上使用setvbuf可以關閉庫緩沖)。

基本上,如果你要緩沖自己,你想要禁用庫的緩沖,因為它只會讓你感到痛苦。 我不知道是否有任何方法可以為STL I / O做到這一點,所以我建議你去C級I / O.

暫無
暫無

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

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