gpt4 book ai didi

c++ - visual c++ - 为什么读取带有 unsigned char ifstream 的文件比使用 char ifstream 慢得多

转载 作者:行者123 更新时间:2023-11-30 00:46:19 28 4
gpt4 key购买 nike

我一直在测试使用 Visual Studio 在 C++ 中读取文件的性能,我得到了一些我真的不明白的结果。

我的代码如下:

std::vector<unsigned char> Method1(std::string filePath)
{
std::basic_ifstream<unsigned char> file(filePath, std::ios::binary);

file.seekg(0, std::ios::end);
std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);

std::vector<unsigned char> buffer(size);
file.read(buffer.data(), size);

return buffer;
}

(我实际上使用了 uint8_t 而不是 unsigned char,但因为它只是一个 typedef,所以我在这里使用后者来更好地演示问题)

我给它一个 3mb 的文件来读取并使用 std::chrono 函数对其计时,这些是我的结果:
调试配置 - 10.2 秒
发布配置 - 98 毫秒

调试和发布之间的巨大差异已经引起关注。

所以我尝试用“char”替换所有对“unsigned char”的引用(std::basic_ifstream 而不是 std::basic_ifstream 等)并重新运行程序。
我发现它在调试和发布时的运行时间都不到 3 毫秒。

经过一番折腾,我意识到 basic_ifstream 是问题所在。如果我保留其他所有内容并将文件更改为 basic_ifstream (也使用 reinterpret_cast (buffer.data())),那么它也能正常工作。

我已经在两台不同的机器上对此进行了验证,一台运行最新发布的 Visual Studio 2015 版本,另一台运行 Visual Studio 15 的预览版 3。

是否有某种微妙之处导致 basic_ifstream 在使用无符号字符时表现如此糟糕?

最佳答案

您所看到的某些内容几乎可以肯定是缓存造成的。

在 3 毫秒内读取一个 3 MB 的文件意味着您以每秒 1000 兆字节或大约每秒 8 吉比特的速度读取文件(暂时忽略帧等)。

SATA 3 连接的理论最大速度为每秒 6 吉比特,但还有 8b/10b 编码,因此您可以期望的最大可见速度为每秒 4.8 吉比特——刚好超过您获得的速度的一半.

真正的驱动器比这更受限制。典型的旋转硬盘驱动器限制在每秒 130 兆字节左右。快速 SSD 可以将其提高到大约 500 MB/s 左右。因此,除非您的 RAID 配置有至少 16 个可用的快速 SSD,否则您不会仅在 3 毫秒内从磁盘读取 3 MB 的文件(并且 RAID Controller 会增加自己的一些开销,因此要可靠地获得这种速度,您可能需要 18 或 20 个快速 SSD。

您遇到的下一个瓶颈是 PCIe 总线。 PCIe 3.0 理论上每个 channel 的最大带宽约为 985 MB/s,因此您的 RAID Controller 需要使用大约 9 个 channel 来快速传输数据——如果超过 8 个,下一个合理的步骤(可能)是16. 大多数 RAID Controller 只使用 4 channel ,其中相当一部分也只使用 PCIe gen 2。这使它们远远低于您所谈论的带宽(大约四分之一的带宽)。我所知道的最快的 RAID Controller (八千系列 Adaptec)都使用 8 channel PCIe 板。我不知道有任何 16 channel PCIe RAID Controller 。

明显的替代方案是从主内存中读取相当数量的数据。大多数操作系统都会在主内存中缓存数据,因此如果您(相对)快速地连续两次读取相同的数据,那么第二次您将从内存中读取数据,而不是从磁盘传输数据。

换句话说,第一次读取数据时,您有时间从实际存储设备中读取数据。随后的读取尝试(在第一次之后很快发生)可以从主内存中的缓存中检索数据,通常可以大大更快地访问(这正是他们首先进行缓存的原因)。

现在几乎不可能猜出您看到的差异有多少真正归因于您的代码差异,以及有多少归因于缓存——但考虑到您获得的带宽,没有真正的问题余地您所看到的大部分内容一定是由于缓存,因为您实际上几乎不可能从存储设备中如此快速地读取数据。

关于c++ - visual c++ - 为什么读取带有 unsigned char ifstream 的文件比使用 char ifstream 慢得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38958814/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com