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

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

有关完整的背景,请阅读Q和A here – 但除此之外情况可以归结为我有大量的垫子*我需要随意和快速访问.主要的复杂因素是全部数据远远高于可用的RAM量.

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

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

我想我得到了概念,但是当涉及到实际的实现时,我正在翻阅大拇指:

>这是一个通用的C考虑因素,还是我需要在openCV级别解决的问题?
>是否像使数据的粒度接近(但不超过)4KB一样简单? (有关4KB动机,请参阅解决方案here)
>如何在磁盘上保存,访问和表示垫子? (请问memory-mapping是如何参与的?)

最佳答案

Is this a generic C++ consideration, or something I need to address at the openCV level?

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

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

Is it as simple as making the granularity of the of data close to (but not over) 4KB? (see the solution here for the 4KB motivation)

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

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

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

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

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

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

How would the mat(s) actually be saved, accessed and represented on disk? (is this how memory-mapping is involved?)

Swap space / the pagefile is the backing store for your process’s address space.所以,是的,如果您在mmaping之前将内存分配给一个大文件而不是匿名分配,那么它非常类似于您所获得的内容.

点赞