C++ 使用内存中的文件
据我所知,如果我们加载任何文件一次进行读取,那么它将按照LRU algo保持在RAM中,直到没有被其他文件交换 在我的C程序中,我正在加载124MB文本文件以读取其内容。理想情况下,一旦我执行它应该在RAM中,下次当我执行相同的程序时,它应该只从RAM中获取它 但在这里,这两种情况下所用的时间都是15s,与我执行同一程序的时间无关 由于缓存大小非常有限,如3MB,因此无法将其放入缓存中 为了加快程序的执行,还有什么其他的替代方法 更新: 代码链接: -此文件包含main()类并执行分类作业C++ 使用内存中的文件,c++,c,caching,memory-management,C++,C,Caching,Memory Management,据我所知,如果我们加载任何文件一次进行读取,那么它将按照LRU algo保持在RAM中,直到没有被其他文件交换 在我的C程序中,我正在加载124MB文本文件以读取其内容。理想情况下,一旦我执行它应该在RAM中,下次当我执行相同的程序时,它应该只从RAM中获取它 但在这里,这两种情况下所用的时间都是15s,与我执行同一程序的时间无关 由于缓存大小非常有限,如3MB,因此无法将其放入缓存中 为了加快程序的执行,还有什么其他的替代方法 更新: 代码链接: -此文件包含main()类并执行分类作业 -此
-此文件包含用于读取文件和执行分类的功能如果您将文件作为一个整体读取,则如果您的操作系统将其缓存,则该文件将位于RAM中。如果在两次运行之间,缓存压力使您的操作系统(例如Linux内核)丢弃加载的文件,那么您的文件将再次从磁盘读取 但是,您的程序无法控制文件是否来自缓存。操作系统为您的程序提供的文件,无论是来自磁盘还是来自文件缓存,都不在您的控制范围之内
在这篇小文章中可以找到更多的信息:如果您将文件作为一个整体来阅读,那么如果您的操作系统将其缓存,那么该文件将位于RAM中。如果在两次运行之间,缓存压力使您的操作系统(例如Linux内核)丢弃加载的文件,那么您的文件将再次从磁盘读取 但是,您的程序无法控制文件是否来自缓存。操作系统为您的程序提供的文件,无论是来自磁盘还是来自文件缓存,都不在您的控制范围之内
在这篇小文章中可以找到更多信息:一旦您的文件第一次被读取,在正常配置的操作系统下,相关的磁盘页面很可能被有效缓存 假设其他进程不需要此内存,第二次读取将比第一次快得多 作为快速测试,我们生成一个随机文件并计算md5sum两次(Linux中的示例): 在删除缓存的页面后,观察巨大的差异 您可能不喜欢这一点,原因如下:
- 当您第一次读取文件时,该文件实际上已经被缓存(很可能)
- 此磁盘或分区禁用缓存,或文件系统/设备不支持缓存(可能性很小)
- 当您第一次读取文件时,该文件实际上已经被缓存(很可能)
- 此磁盘或分区禁用缓存,或文件系统/设备不支持缓存(可能性很小)
fscanf
或使用fstream
)以小增量读取文件
尝试以大数据块(1-16MB)读取文件,并在该缓冲区上进行处理
如果有很多I/O调用来读取文件,那么从内核模式来回切换到用户模式以及其他请求I/O的进程会导致大量开销
编辑:
大量调用fscanf
和get
。尝试将整个文件读入一个缓冲区,然后使用该缓冲区。使用read
(而不是fread
)一次性读取文件
如果文件太大,请将其拆分为1MB读取
Edit2
在函数read\u model
中,将fscanf
替换为sscanf
,以处理缓冲区。一次性将所有模型读取到文件大小的大缓冲区。可以使用
stat
找到文件大小。不要使用fgets
而是使用strtok
迭代缓冲区。后者可用于在迭代新行时用空字符替换新行
如果您不知道这些函数中的任何一个,请尝试用谷歌搜索
manfuncname
。例如,manstrktok
在一个像样的SSD上加载一个120MB的文件应该不到1秒。对于硬盘驱动器,2-3秒。我可以假设您不以大块方式读取文件,而是使用标准库中的函数(例如fscanf
或使用fstream
)以小增量读取文件
尝试以大数据块(1-16MB)读取文件,并在该缓冲区上进行处理
如果有很多I/O调用来读取文件,那么从内核模式来回切换到用户模式以及其他请求I/O的进程会导致大量开销
编辑:
大量调用fscanf
和get
。尝试将整个文件读入一个缓冲区,然后使用该缓冲区。使用read
(而不是fread
)一次性读取文件
如果文件太大,请将其拆分为1MB读取
Edit2
在函数read\u model
中,将fscanf
替换为sscanf
,以处理缓冲区。一次性将所有模型读取到文件大小的大缓冲区。可以使用
stat
找到文件大小。不要使用fgets
而是使用strtok
迭代缓冲区。后者可以
$ 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