大约 2Gb 后 C++ ofstream 写入性能下降

Posted

技术标签:

【中文标题】大约 2Gb 后 C++ ofstream 写入性能下降【英文标题】:Decrease of the C++ ofstream write performance after around 2Gb 【发布时间】:2021-05-15 02:46:34 【问题描述】:

我目前正在编写一个 C++ 程序,该程序需要通过顺序写入缓冲区来将大量数据写入文件(通常约为 5Gb)。 在本例中,我将 400Mb 的缓冲区写入 std::ofstream。我的磁盘是 SSD,几乎是空的。 4个缓冲区后,写入性能下降。有人知道为什么以及是否可以避免吗?

这是我的代码:

#include <iostream>
#include <iomanip>
#include <fstream>
#include <chrono>

int main()

  unsigned int bufferSize = 4e8; //400Mb
  unsigned char* buffer = new unsigned char[bufferSize];
  for (unsigned int i = 0; i < bufferSize; i++)
    buffer[i] = (unsigned char) i % 256; // just "randomly" writing the buffer
  std::ofstream ofs("test.bin");
  std::chrono::steady_clock::time_point start_time;
  std::chrono::steady_clock::time_point stop_time;
  std::chrono::duration<double> duration;

  for (int i = 1; i <= 10; i++)
  
    start_time = std::chrono::steady_clock::now();
    ofs.write((char*) buffer, bufferSize);
    stop_time = std::chrono::steady_clock::now();
    duration = stop_time - start_time;
    std::cout << "i = " << i << ", time spent copying the buffer = " << std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count() / 1e6  << "ms" << std::endl;
  

  ofs.close();
  delete[] buffer;
  return 0;

这是我运行它时得到的结果:

nirupamix@machine:~/$ ./main.out
i = 1, time spent copying the buffer = 166.267ms
i = 2, time spent copying the buffer = 170.698ms
i = 3, time spent copying the buffer = 177.484ms
i = 4, time spent copying the buffer = 210.693ms
i = 5, time spent copying the buffer = 475.933ms
i = 6, time spent copying the buffer = 793.295ms
i = 7, time spent copying the buffer = 822.195ms
i = 8, time spent copying the buffer = 828.539ms
i = 9, time spent copying the buffer = 850.651ms
i = 10, time spent copying the buffer = 794.542ms

感谢您的宝贵时间!

【问题讨论】:

您的 ssd 的预期速度是多少?通常的 SATA SSD 限制为 600 MB/S。 安装更多内存,以便您的操作系统有更多缓存可供使用。 不确定它是否相关(因此是评论而不是答案),但我记得旧文件系统在达到一定大小后使用间接寻址块。不确定是否有较新的,特别是在 SSD 硬件上... 不相关,但如果您正在写入二进制数据,则应使用std::ios::binary open-mode。正如其他人指出的那样,这看起来像是一个可能发生在操作系统驱动程序级别的缓存事情,而您实际上受到磁盘速度和缓存大小的限制。如果您在每次写入之间暂停一秒钟,我想您不会看到这样的减速。如果您需要更高的持久数据速率,则需要构建一个包含多个驱动器的 RAID 卷。 注意:MB 与 Mb,大小写很重要,其中一个单位是另一个单位的八倍(字节与位)。 ;无论如何,这可能取决于操作系统(你的操作系统是什么?),例如Linux 将快速确认初始写入,一旦要写回磁盘的 RAM 量增长到一定比例以上,它会将写入速度减慢到接近底层磁盘的速度,您可能会在此处看到。您可以尝试在写入后添加fsync,这应该可以让您看到磁盘的实际速度(或慢速)。 【参考方案1】:

将大量数据写入 SSD 时可能会出现几个问题

终端节流 - 当数据写入时间足够长时,SDD 会升温并变慢 您的数据不应足够大。 SSD 缓存已满 根据您的 SSD 的使用年限和技术,您的 SSD 可能有一些 DRAM 来缓存写入,然后再进入较慢的 SLC 缓存,最后如果实际 QLC 存储已满。 (更多信息请访问anandtech。

【讨论】:

以上是关于大约 2Gb 后 C++ ofstream 写入性能下降的主要内容,如果未能解决你的问题,请参考以下文章

❥关于C++之写入/读取文本文件

数组 C++ 的 Ofstream 文本写入问题

C++ ofstream向文件写数据?

std::ofstream,写入前检查文件是不是存在

std::ofstream,写入前检查文件是不是存在

C++中,ifstream和ofstream定义文件流的区别