【发布时间】:2014-03-23 18:04:57
【问题描述】:
我有一个动态分配的 struct 数组,包含 1700 万个元素。为了将它保存到磁盘,我写了
fwrite(StructList, sizeof(Struct), NumStructs, FilePointer)
在后面的步骤中,我使用等效的 fread 语句读取它,即使用 sizeof(Struct) 和计数 NumStructs。我预计生成的文件大约为 3.5 GB(这都是 x64)。
是否可以通过 sizeof(Struct) * NumStructs 作为大小和 1 作为计数来加快速度?我对为什么在具有 32 GB RAM(大量写入缓存)的快速计算机上写入操作可能需要 分钟 感到头疼。我已经运行了自制的基准测试,并且缓存足够激进,前 800 MB 到 1 GB 的速度通常为 400 MB/秒。 PerfMon 显示它在 fwrite 期间消耗了一个内核的 100%。
我看到了here 的问题,所以我要问的是,fwrite 中是否有一些循环可以通过告诉它写入 1 个大小为 n*s 而不是 n 的元素来“欺骗”它更快地运行大小为 s 的元素。
编辑
我在发布模式下运行了两次,两次都放弃了等待。然后我在调试模式下运行它,知道通常fwrite 操作需要更长的时间。要写入的数据的确切大小是 4,368,892,928 字节。在所有这三种情况下,PerfMon 都显示了两次磁盘写入活动的爆发,间隔大约 30 秒,之后 CPU 达到一个内核的 100%。该文件当时为 73,924,608 字节。我在fwrite 的两侧都有断点,所以我知道它所在的位置。确实似乎有什么东西卡住了,但我会让它运行一夜然后看看。
编辑
一夜之间,它肯定挂在fwrite,文件从未超过 70 MB。
【问题讨论】:
-
你试过了吗?为了防止缓存妨碍您,您可以使用其他应用程序来占用内存的其余部分。
-
这样改变参数不会影响性能;如果有一个简短的写入,它只会影响错误报告。 IMO,您无能为力来提高性能。通过只需要一次调用,您已将系统调用开销降至最低;从那里开始,问题是 o/s 可以多快分配 3.5 GiB 磁盘空间。您可以寻找系统调用来预配置文件大小并使分配尽可能接近顺序,但这是非常特定于平台的。我看到您的标签中有 Windows;我无能为力...
-
如果您的程序正在燃烧 100% 核心,那么它不会被磁盘卡住。这使您认为它与 fwrite() 有任何关系的假设非常弱。不信任任何反恶意软件并使用分析器。
-
1.您确实知道
fwrite使用缓冲区 - 原始的write会更好。 2. 改变设计——为什么要从磁盘读取/写入大量数据。 -
您没有提供编译器或运行时库。您的文件足够大,字节数足以溢出 32 位无符号 size_t。一个可怜的或旧的 crtl 可能会搞砸这个。
标签: c windows visual-studio-2012 file-io