优化数据结构,以便利用虚拟内存

时间:2016-04-19 01:52:49

标签: c++ performance opencv caching memory-management

我想知道如何优化openCV中的数据结构(特别是mat类型),以便我能够利用内存/虚拟内存管理中内置的操作系统。

有关完整的背景信息,请阅读Q和A here - 但其他情况可以归结为我有大量的垫子 * ,我需要访问任意迅速。主要的复杂因素是全部数据远远高于可用RAM的数量。

(*从概念上讲,数据是一个递归定义的3D阵列3D阵列,但是让我们不要混淆水!)

我宁愿让操作系统为我这样做,而不是构建我自己的LRU缓存和RAM饥饿且低效的“页面”寻址策略来访问它。

我想我已经掌握了这些概念,但是当涉及到实际的实施时,我正在翻阅大拇指:

  • 这是一个通用的C ++考虑因素,还是我需要在openCV级别解决的问题?

  • 是否只是使数据的粒度接近(但不超过)4KB? (有关4KB动机,请参阅解决方案here

  • 如何在磁盘上保存,访问和表示垫子? (这是memory-mapping涉及的方式吗?)

1 个答案:

答案 0 :(得分:1)

  

这是一个通用的C ++考虑因素,还是我需要在openCV级别解决的问题?

您只需分配并使用大量内存。 分页/虚拟内存的全部意义在于它是完全透明的。一切都非常慢,但仍在继续工作。在你没有交换空间+ RAM之前,你不会得到ENOMEM

在普通的Linux系统上,您的正常交换分区应该非常小(低于1GB),因此您可能需要dd交换文件,mkswap / swapon在上面。确保交换文件仅具有root用户的读写权限。显然,每个主要操作系统都有自己的程序。

  

是否只是将数据的粒度接近(但不超过)4KB? (请参阅此处有关4KB动机的解决方案)

如果您有指向其他数据的指针,请确保将它们保存在一起。您希望所有小的“热”数据只在几页中,而体面的OS LRU算法不会分页。

如果您将热数据与冷数据混合在一起,它将很容易被分页并导致额外的页面文件往返,之后甚至可能发生最终数据的缓存未命中。

与Yakk一样,顺序访问模式会做得更好,因为磁盘I / O在多块读取时表现更好。 (即使SSD使用更大的块也具有更好的吞吐量)。这也允许预取,这允许一个I / O请求在前一个数据到达之前启动。最大化I / O吞吐量需要流水线请求。

尽可能设计算法以进行顺序访问。这在所有级别的内存中都是有利的,从分页一直到L1高速缓存。顺序存取甚至可以使用向量寄存器进行自动矢量化。

Cache blocking (aka loop tiling)技术也适用于页面未命中。谷歌的详细信息,但主要的想法是在数据的子集上执行算法的所有步骤,而不是在每一步触摸所有数据。然后,每个数据只需要一次加载到缓存中,而不是一次加载到算法的每一步。

将DRAM视为巨型虚拟地址空间的缓存。

  

如何在磁盘上保存,访问和表示垫子? (这是如何涉及内存映射的?)

Swap space / the pagefile is the backing store for your process's address space。所以,是的,如果您通过mmaping大文件分配内存而不是进行匿名分配,则非常类似于此。