我编写了一个程序,用于将 2d 阵列读写到 NVME SSD(三星 970EVO plus)中。
我设计的程序可以像 as 一样读取 N*M
#pragma omp parallel for
for(int i=0;i<N;i++)
fstream.read(...) // read M bytes
但是,此代码显示的性能(KB/s)低于 SSD 规范(< GB/s)
我认为如果大小 M 大于 block 大小(可能是 4KB)并且是 2 的倍数,则该代码将显示 GB/s 性能。
然而,事实并非如此。我想我错过了一些东西。
是否有一些 C++ 代码可以最大限度地提高 SSD 上的 I/O 性能?
最佳答案
无论你说多少fstream
阅读起来,很可能会读完 a fixed size streambuf buffer 。 C++ 标准没有指定其默认大小,但 4kb 相当常见。因此将 4mb 大小传递给 read()
很可能最终会有效地将读取 4kb 数据的调用减少到 1024 次。这可能解释了您观察到的表现。您不是一次读取大量数据,而是您的应用程序进行多次调用来读取较小的数据 block 。
C++ 标准确实提供了通过 pubsetbuf
调整内部流缓冲区大小的方法。方法,并将其留给每个 C++ 实现来准确指定何时以及如何配置具有非默认大小的流缓冲区。您的 C++ 实现可能允许您仅在打开 std::ifstream
之前调整流缓冲区的大小。 ,或者它可能不允许您调整 std::ifstream
的大小的默认流缓冲区大小;相反,您必须首先构建自定义流缓冲区实例,然后使用 rdbuf()
将其附加到 std::ifstream
。有关详细信息,请参阅 C++ 库的文档。
或者,您可能希望考虑使用操作系统的 native 文件输入/输出系统调用,并完全绕过流缓冲区库,这也会增加一些开销。文件的内容很可能首先被读入流缓冲区,然后复制到您在此处传递的缓冲区中。调用 native 文件输入系统调用将消除这种冗余拷贝,从而提高性能。
关于c++ - 如何在 C++ 中最大化 SSD I/O?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59350169/