操作系统从磁盘中读取的内容比程序实际要求的要多,因为程序将来可能需要附近的信息。在我的应用程序中,当我从磁盘中获取项目时,我想显示围绕元素的信息间隔。我要求和显示的速度有多少信息与速度之间有折衷。但是,由于OS已经读取的内容超出了我要求的内容,因此在内存中访问这些字节是免费的。我可以使用什么API来找出操作系统缓存中的内容?

另外,我可以使用内存映射的文件。在这种情况下,问题减少了找出页面是否交换为磁盘。这可以在任何常见的操作系统中完成吗?

编辑:相关论文 http://www.azulsystems.com/events/mspc_2008/2008_mspc.pdf

有帮助吗?

解决方案

您确实可以至少在Linux上使用第二种方法。 mmap() 文件,然后使用 mincore() 功能以确定哪些页面是居民。从男人页面:

int mincore(void *addr, size_t length, unsigned char *vec);

mincore() 返回向量,该向量指示了调用过程的虚拟内存页面是否属于Core(RAM),因此如果引用了磁盘访问(页面故障)。内核返回有关从地址开始的页面的居住信息 addr,继续 length 字节。

当然这里有种族条件 - mincore() 可以告诉您一个页面是居民,但是在您访问该页面之前,它可能会换成。 这就是生活.

其他提示

您从错误的推定开始。至少在Linux上,操作系统将尝试找出程序的访问模式。如果您顺序读取文件,则内核将顺序进行预取。如果您经常跳动文件,则一开始可能会混淆内核,但随后将停止预取。

所以如果你真的 顺序访问文件,您知道可能是预取的内容:下一个数据块。如果您是随机寻求的,那么附近可能没有其他任何东西。

尝试以不同的方式处理这一点。在致电read()获取您的信息之前 需要, , 称呼 fadvise() 让操作系统知道你什么 它开始加载..

我也很想知道您使用的是哪种应用程序可以通过仅在文件缓存中偶然地操作的数据来正确运行。我觉得如果您发布了更多信息,我们可以找到一种满足您需求的好方法。

当然,它不能在Windows上完成。在Windows上,读取的前方行为取决于操作系统,即使它可以告诉您它已经阅读了多少,它也不会对您有任何好处用于缓存本可以用于其他用途。

确定页面是否居民也是如此。一旦发现,当其他一些线程需要内存的其他内容时,答案就可能会发生变化。

如果您真的想在窗户上做一些事情,则可以关闭缓冲并自行管理缓冲区。这是最快的IO路径,但它也是最复杂的 - 您必须非常小心,而且操作系统通常仍然可以做得更好。

我可以使用什么API来找出操作系统缓存中的内容?

对于任何POSIX系统,当然没有标准的方法,我不知道任何特定于Linux的非标准方法。您唯一可以肯定地知道的是,该文件系统将以页面大小的倍数(通常为4KB)读取。因此,如果您的阅读很小,您可以很高的可能性(尽管不确定)知道周围页面中的数据在内存中。

我想,您可以做一些棘手的事情,例如时间读取系统要完成多长时间。如果快速,那是100秒或以下的100秒,那可能是一个缓存的命中。一旦到达毫秒左右,可能就是一个缓存的错过。当然,这实际上并没有太大帮助,而且非常非常脆弱。

请注意,一旦文件系统将数据复制到用户缓冲区,就可以免费丢弃持有数据的缓冲区。它可能不会立即这样做,但是您无法确定。

最后,我第二 @Karmastan的建议:解释您要实现的更广泛的目的。可能有一种方法可以做到,但是您建议的不是。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top