C 使用fgets随机读取非常大的文件似乎会带来Windows缓存';s极限
我已经为Windows7-64位编写了一个C/C++程序,可以处理非常大的文件。在最后一步中,它从输入文件(10GB+)中读取行,并将其写入输出文件。对输入文件的访问是随机的,写入是顺序的。 编辑:这种方法的主要原因是减少RAM的使用 在阅读部分,我基本上是这样做的:(对不起,非常简短,可能有问题) 通常这段代码很好,不是说快,但在一些非常特殊的条件下,它会变得非常慢。这种行为似乎不是确定性的,因为性能下降发生在文件其他部分的不同机器上,甚至根本没有发生。甚至到目前为止,程序完全停止读取,而没有光盘操作 另一个交响曲似乎是用过的公羊。我的进程使它的RAM保持稳定,但系统使用的RAM有时会增长得很大。在使用一些RAM工具后,我发现Windows映射文件会增长到几GB。这种行为似乎也取决于硬件,因为它发生在过程的不同部分的不同机器上 据我所知,SSD上不存在这个问题,所以它肯定和HDD的响应时间有关 我的猜测是Windows缓存在某种程度上变得“wierd”。只要缓存工作,程序就会运行得很快。但是,当缓存出错时,这种行为会变成“停止读取”或“增大缓存大小”,有时甚至两者兼而有之。由于我不是windows缓存算法的专家,我很乐意听到一个解释。还有,有没有办法让Windows脱离C/C++来操作/停止/强制执行缓存 由于我研究这个问题已经有一段时间了,我已经尝试了一些技巧,但没有成功:C 使用fgets随机读取非常大的文件似乎会带来Windows缓存';s极限,c,windows,caching,64-bit,large-files,C,Windows,Caching,64 Bit,Large Files,我已经为Windows7-64位编写了一个C/C++程序,可以处理非常大的文件。在最后一步中,它从输入文件(10GB+)中读取行,并将其写入输出文件。对输入文件的访问是随机的,写入是顺序的。 编辑:这种方法的主要原因是减少RAM的使用 在阅读部分,我基本上是这样做的:(对不起,非常简短,可能有问题) 通常这段代码很好,不是说快,但在一些非常特殊的条件下,它会变得非常慢。这种行为似乎不是确定性的,因为性能下降发生在文件其他部分的不同机器上,甚至根本没有发生。甚至到目前为止,程序完全停止读取,而没有
- filePointer=fopen(文件名,“rbR”)//只需填充缓存,直到RAM已满
- 大量的读/写缓冲,以防止二者相互影响
提前感谢对于任何缓存算法来说,对一个巨大的文件进行真正的随机访问是最糟糕的情况。最好关闭尽可能多的缓存 有多个级别的缓存:
- CRT库(因为您使用的是f函数)
- 操作系统和文件系统
- 可能是驱动器本身
您可能还必须重新考虑您的算法是如何工作的。搜索真的是随机的吗?你能把它们重新排序吗,也许是分批排序,这样它们就排列整齐了?您可以一次限制对文件中相对较小区域的访问吗?你能把大文件分成小文件,然后一次处理一个文件吗?您检查过驱动器和特定文件的碎片级别了吗?对于任何缓存算法来说,对一个大文件进行真正的随机访问都是最糟糕的情况。最好关闭尽可能多的缓存 有多个级别的缓存:
- CRT库(因为您使用的是f函数)
- 操作系统和文件系统
- 可能是驱动器本身
您可能还必须重新考虑您的算法是如何工作的。搜索真的是随机的吗?你能把它们重新排序吗,也许是分批排序,这样它们就排列整齐了?您可以一次限制对文件中相对较小区域的访问吗?你能把大文件分成小文件,然后一次处理一个文件吗?您是否检查了驱动器和特定文件上的碎片级别?根据应用程序所做的工作的大局,您可能会采取不同的方法-可能是这样的:
这无疑是一种更复杂的方法,但它会对缓存子系统更友好,因此可能会有更好的性能。根据应用程序的总体情况,您可能会采取不同的方法-可能是这样的:
void seekAndGetLine(char* line, size_t lineSize, off64_t pos, FILE* filePointer){
fseeko64(filePointer, pos, ios_base::beg);
fgets(line, lineSize, filePointer);
}