在内存文件中使用
Working with in memory file
据我了解,如果我们加载任何文件一次进行读取,那么它就会按照 LRU 算法保留在 RAM 中,直到不被其他文件交换。
在我的 C 程序中,我正在加载 124MB 的文本文件来读取它的内容。理想情况下,一旦我执行它应该在 RAM 中,下次当我很快执行相同的程序时,它应该只从 RAM 中获取它。
但是在这两种情况下花费的时间只有 15 秒,而不考虑我执行同一程序的时间。
由于缓存大小非常有限,例如 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 - 此文件包含用于读取文件和执行分类的功能
首次读取文件后,在正常配置的操作系统下,很可能有效地缓存了所涉及的磁盘页面。
假设其他进程不需要此内存,第二次读取将比第一次读取快得多。
作为快速测试,我们生成一个随机文件并计算两次 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
观察删除缓存页面后的巨大差异。
您可能不欣赏这一点的原因如下:
- 该文件实际上在您第一次读取时已经缓存(很可能(
- 此磁盘或分区禁用缓存,或者文件系统/设备不支持缓存(非常不可能(。
在体面的 SSD 上加载 120MB 文件应该需要不到 1 秒的时间。 硬盘需要 2-3 秒。 我可以假设您不是以大块读取文件,而是使用标准库中的功能以小增量读取它(例如 fscanf
或使用fstream
(。
尝试以大块 (1-16MB( 读取文件,并在该缓冲区上进行处理。
如果读取文件时有大量 I/O 调用,则由于从内核模式到用户模式和其他要求 I/O 的进程来回切换,会产生大量开销。
编辑: 很多电话给fscanf
和gets
。尝试将整个文件读取到单个缓冲区并使用该缓冲区。使用read
(不是fread
(一次性读取文件。
如果文件太大,请将其拆分为 1MB 读取。
编辑2
在函数中read_model
将fscanf
替换为sscanf
以处理缓冲区。
一次性将所有模型读取到文件大小的大缓冲区。文件大小可以使用stat
找到。 不使用fgets
而是使用 strtok
迭代缓冲区。 后者可用于在迭代新行时用 NULL 字符替换新行。
如果您不知道这些功能中的任何一个,请尝试在谷歌上搜索man funcname
。 例如 man strktok
.
如果您将文件作为一个整体读取,则如果您的操作系统缓存该文件,该文件将位于 RAM 中。如果在两次运行之间,缓存压力使您的操作系统(例如 Linux 内核(丢弃加载的文件,您的文件将再次从磁盘读取它。
但是,程序无法控制文件是否来自缓存。操作系统为您的程序提供文件,无论是来自磁盘还是从文件缓存都超出了您的控制范围。
可以在这篇小文章中找到更多信息:Linux 磁盘缓存的实验和乐趣
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- C/C++ - 查询平台相关的换行符(用于内存映射文件)
- WinVerifyTrust 仅在使用文件而不是内存 blob 时才有效
- 如何在多写入器情况下对文件支持的共享内存中的大页面出错
- 在指向现有内存地址的 hpp 文件中声明成员函数的最佳方法
- 内存映射文件访问非常慢
- 我正在尝试创建一个C++映射,该映射在boost内存映射文件中具有向量值
- 这些结构在文件中的大小不同,但在程序内存中的大小相同
- 在嵌入式系统中读取文件的内存碎片
- 如何从文件中读取 100x24 矩阵并将其作为浮点矩阵保存在内存中?
- 测量任何 Windows 可执行文件的内存使用情况和执行时间
- 提升进程间共享内存删除、权限和输出文件
- 将内存文件添加到 clang 编译器实例
- 为什么我的 C++ 程序在执行 TCMALLOC 堆检查器或堆配置文件时使用大量内存
- C++ 从磁盘读取文件并将其写入共享内存
- 为什么在编译时需要知道对象的内存配置文件以进行堆栈放置?
- 为什么 du -sh 输出错误大小的内存映射文件
- 将内存保存到文件并加载它而不必解析数据?
- 将提升管理的共享内存写入文件
- C++类似于 std::vector / boost::array 的文件内存映射容器