使用内存文件

时间:2014-09-29 12:41:27

标签: c++ c caching memory-management

据我了解,如果我们加载任何文件一次以便读取,那么它将保留在RAM中,每个LRU算法 直到不被其他文件交换。

在我的 C程序中,我正在加载 124MB 文本文件以读取其内容。理想情况下,一旦我执行它应该在RAM中,下次当我很快执行相同的程序时,它应该只从RAM中获取它。

但是这两种情况下的时间仅为 15s ,而不考虑我执行相同程序的时间。

由于缓存大小非常有限,如 3MB ,因此无法放入内部缓存。

有什么其他替代方法可以加快程序的执行?

更新

代码链接:

http://webdocs.cs.ualberta.ca/~sajib/cmput606/project/code/svm_classify.c - 此文件包含main()类并执行分类作业

http://webdocs.cs.ualberta.ca/~sajib/cmput606/project/code/svm_common.c - 此文件包含用于读取文件和执行分类的函数

3 个答案:

答案 0 :(得分:3)

首次读取文件后,在正常配置的操作系统下,所涉及的磁盘页面很可能被有效缓存。

假设其他进程不需要此内存,则第二次读取将比第一次读取快。

作为一个快速测试,我们生成一个随机文件并计算两次md5sum(例如在Linux中):

$ dd if=/dev/urandom of=/tmp/readtest count=124 bs=1M

$ echo 3 > /proc/sys/vm/drop_caches  # needs to be run as root

$ time md5sum /tmp/readtest 
f788abe8a8d120a87bb293e65e5d50ff  /tmp/readtest

real    0m5.706s
user    0m0.332s
sys 0m0.072s

$ time md5sum /tmp/readtest 
f788abe8a8d120a87bb293e65e5d50ff  /tmp/readtest

real    0m0.295s
user    0m0.268s
sys 0m0.024s

删除缓存页面后观察巨大差异。

你有理由不理解这一点:

  • 当您第一次阅读该文件时(最有可能)
  • ,该文件实际上已经被缓存
  • 此磁盘或分区禁用缓存,或者文件系统/设备不支持缓存(非常不可能)。

答案 1 :(得分:2)

在一个体面的SSD上加载一个120MB的文件应该不到1秒。硬盘驱动器需要2-3秒。我可以假设您没有以大块读取文件,而是使用标准库中的函数(例如fscanf或使用fstream)以小增量读取它。

尝试以大块(1-16MB)读取文件并在该缓冲区上进行处理。

如果有大量的I / O调用来读取文件,那么从内核到用户模式以及其他要求I / O的进程来回切换会产生很多开销。

修改  很多来自fscanfgets的来电。尝试将整个文件读取到单个缓冲区并处理该缓冲区。使用read(不是fread)一次性读取文件。

如果文件太大,请将其拆分为1MB读数。

<强> EDIT2

在函数read_model中,将fscanf替换为sscanf以处理缓冲区。
将所有模型一次性读取到文件大小的大缓冲区。可以使用stat找到文件大小。而不是使用fgets使用strtok迭代缓冲区。后者可用于在迭代它们时用NULL字符替换新行。

如果您不了解这些功能,请尝试使用Google搜索man funcname。例如。 man strktok

答案 2 :(得分:1)

如果您整个读取文件,如果您的操作系统缓存该文件,该文件将在RAM中。如果在两次运行之间,缓存压力使您的操作系统(以Linux内核为例)丢弃加载的文件,则您的文件将再次从磁盘读取它。

但是,您的程序无法控制文件是否来自缓存。操作系统为您的程序提供文件,无论是从磁盘还是文件缓存都在您的控制之外。

在这篇小文章中可以找到更多信息:Experiments and fun with the Linux disk cache