高效稀疏访问大型内存映射文件

时间:2012-02-17 16:41:36

标签: windows memory-management virtual-memory

我们在大型(例如700 MB)文件中有图像数据。这些文件是在Windows 7 64位上映射的内存。

对图像数据的一些操作涉及我们从图像的每一行读取几个字节。这可能很慢 - 没有行比页面大,所以我们得到每行的页面错误,即使我们只读取几个字节。在我们当前的实现中,我们无法看到这一点,但是我们希望确保我们能够充分利用磁盘系统。

为了获得最佳性能,我们希望在我们处理当前数据时,我们可以提示VM系统获取下一个图像行(可能导致页面错误)。这将并行处理我们的处理和页面错误。在Windows上似乎没有明显的方法可以做到这一点!

所以问题:

  • Windows 7上是否有madvise( MADV_WILLNEED )的等效内容?

  • 有没有办法异步触摸页面,触发页面 错误而不等待页面可用?

正确的长期解决方案是以不同的方式存储我们的数据(例如在磁贴中),但我们现在无法做到这一点。我们现在还需要保持内存映射方法。

2 个答案:

答案 0 :(得分:1)

我认为您不能暗示VM系统,但您可以通过在处理上一行时加载下一行数据来预取数据。您可以将此与处理并行。你应该提前获得超过1,因为处理很可能比从文件读取快得多。

这实际上非常适合生产者 - 消费者模式。使图像阅读器和数据处理器在不同的线程上运行,并使用某种带有容量限制的阻塞集合(如C#BlockingCollection)将数据从阅读器传递到处理器。

答案 1 :(得分:1)

尽管这已经是一个古老的话题了,但我给出了一个实现的实例,只有在你能够很好地理解大局的情况下才能用作设计参考。

我们在一个“大数据”电信应用程序中遇到了挑战,我们比虚拟内存管理器更新,哪些页面应该从稀疏的“巨大文件”中分页。我们所做的是我们有一个专门的线程(“inmemadvisor”)来接收“需求”请求,每个请求都有一个优先级。该线程维护优先级的请求列表,并将内存读取“提示”提交给线程池,其中最大数量的线程处理高优先级请求,池的最小部分处理最低优先级(您可能会得到这个想法)。

然后我们有参数来控制池中的线程数和其他一些漂亮的细节。

此实施的优点是:

  • 我们的性能优于VM默认分页模型的10倍(在Windoze Server 2008/2012中)
  • 只要分页变得“软”并且我们可以忘记我们不再需要的数据(不需要立即用硬故障登录)性能优于好
  • 我们可以利用整个可用的免费物理RAM内存来加速计算
  • 您添加的每个新MB内存都可以提升性能

缺点:

  • 如果你的RAM用完了(地方坏了),性能就会变成猪......好吧,即使没有这个实现也是如此
  • 这需要一些精心设计和良好的实施才值得这样做
  • 在某些应用程序中,您可能需要添加额外的监视和控制逻辑来控制“inmemadvisor”成为一个好公民

因此,简而言之:这是一个相当不会做的事情,但另一方面,这些是使编程成为积极挑战的事情;-)顺便说一下:我们的实现在性能上胜过Linux madvice() em>我们的应用程序,但不像它那样通用。

干杯,// Jari