我有一个存储数据的文件,如下所示
A1 B1 C1 ... A2 B2 C2 ... .... An Bn Cn ...
这里,Ai,Bi和Ci是16字节的块。每个块Ai Bi Ci ...可能> 1M大,n可能是256.我想按顺序读取A1,A2 ...... An,然后依次读取B1,B2 ... Bn ......
如果我正在使用fread A1,fseek到A2,fread A2,...,我猜它浪费了很多IO带宽。 fread可以在每次调用时从磁盘读取4k字节,在我执行fseek后,最后一次fread的缓存数据可能会丢失。读完所有As后,读取B1需要直接从磁盘读取而不是缓存。
这个假设是否正确?我不确定文件系统是否可以智能并且仍然使用B1保留缓存。如果文件系统没有帮助这种情况,我可能必须实现myfread它的fread包装,但缓存256 * 4k数据在我自己的缓冲区中,所以下一轮读取Bs可以更快。 myfread从缓冲区读取,直到达到4k,然后它需要fread真实数据。但我知道fread不是一个简单的API,myfread可以是一个简单的实现吗?我是否需要考虑文件系统的任何一致性?在我的情况下,我知道在我阅读时没有人写文件。
答案 0 :(得分:1)
它不仅仅是文件系统,它还会缓存hdd / ssd。此外,Linux将使用任何备用RAM来尽可能多地缓存文件系统,只有在程序分配内存时才将其丢弃(我不知道如何选择缓存内容)。
大多数事情都会缓存块,并将未使用的数据替换为程序正在使用的数据,或者接近使用的数据。您的稀疏访问对于缓存来说将是一项艰苦的工作。
要考虑的两个选项 - 要么1)将整个文件读入单个数据块并稍后进行细分(RAM中的256MB数据现在没什么,只看Web浏览器内存消耗,它们真的是内存耗尽)或者2)设置RAM驱动器并在使用之前将文件复制到该驱动器。
2)更容易,没有什么比1)
更快