我问这个问题是因为我一直在从事一个需要根据情况快速收集大量数据的项目。每秒 5.7GBytes(大写字节)或每秒 11.4GBytes。
我们正在使用 3 个 Samsung Pro NVME 来处理小型 strip raid 阵列(对于 11.4GB/s,我们有一个更大的阵列)。
目前,该项目是在Windows上开发的,我想让东西尽可能地可移植,所以我专注于使用C++标准库;然而,无论我做什么,我都无法破解文件传输速度超过 1.5GB/s
策略很简单,创建几个巨大的交换缓冲区,并将它们作为一个巨大的未格式化的二进制文件直接写入磁盘。
使用std::ofstream
并通过以下方式手动设置不同的缓冲区大小进行基准测试:
rdbuf()->pubsetbuf(buffer, BUFFER_SIZE);
open(Filename, std::ios::binary|std::ios::trunc);
接着是我的托管写入循环,我找到了最佳点,但始终无法突破 1.5GB/s
然后我找到了 Windows SDK 及其 CreateFile功能
特别是使用FILE_FLAG_NO_BUFFERING创建文件函数标志。
这是一个游戏规则改变者,只要我确保向其提供扇区对齐的数据(在我的情况下,所有数据都需要是 512 字节的倍数),我突然就能够充分利用 raid 阵列吞吐量。
我重新访问了 std::ofstream
尝试使用更多与操作系统无关的功能;然而,即使可以为 std::ofstream
指定零缓冲区,似乎没有任何文档说明在没有缓冲区的情况下使用该函数的任何注意事项。
std::ofstream
允许 64 位值的写入大小,与仅接受 DWORD 设置的 Windows SDK WriteFile 不同,最大写入大小是可以挤入 uint32_t
的 512 的最大倍数。如果你的文件超过 4GB(我的就是这样),你必须循环管理你的写入。
这就提出了一个问题,微软是否根本不让 C++ 标准库开发人员访问必要的操作系统级系统调用来利用超高速驱动器阵列?或者我是否遗漏了如何充分利用 C++ 标准库的潜力?
最佳答案
“微软只是不提供 C++ 标准库开发人员吗……”
您可能会注意到您使用的产品名为 Microsoft Visual Studio。 Visual Studio 标准库开发人员在 Microsoft 工作,尽管与 Windows 开发人员位于不同的团队。
原因有点简单:Visual C++ 开发人员不可能了解并优化所有可能的使用场景。以如此高的速度进行文本格式化有点不寻常。请记住,ostream
的要点就是提供operator<<
。 ofstream
用于格式化输出到文件。但对于高速 I/O,您无论如何都需要二进制输出。
关于c++ - Microsoft 中的 C++ 标准库文件流操作是否已瘫痪?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68495768/