我已经实现了一个多级缓存模拟器,它需要存储模拟器中当前的值。在当前配置下,所有存储值的最大大小可能达到2G。显然,我不会假设这种最坏的情况,并提前分配所有内存。相反,我将程序设置为根据需要以块的形式分配内存。当以前在指定位置没有发生写入时,为了提供0值,我正在calloc
,这一事实加剧了这种分配的开销。
我的问题是,对于每次需要更多内存时应该分配多少内存,是否有一个很好的启发式方法?目前,我使用的是一个任意值,我考虑了一些解决方案,该解决方案将使用总系统内存的某个比率(我认为在编译和/或运行时可以动态检测到这一点),但即使使用了后者,我仍然不太满意使用任意比率
如果您能深入了解此类情况下的最佳实践,我们将不胜感激!
一个常见的经验法则是在每次重新分配时以几何级数增长,例如加倍。
如果这是一个需要优化的问题,最好了解程序的分配模式。这是通过理解程序的实现、程序运行的体系结构以及观察(例如时间和内存分析)来实现的。
事实是,你可以从很多角度进行优化,但事情会随着时间的推移而变化(输入会变化,环境会变化)。在用户领域,你的内存使用情况已经被猜测了。
考虑到您的分配大小,我假设您已经依赖于一个系统,该系统将根据需要默认为后备存储。因此,您无法控制什么内容或何时分页。在这种情况下,窥探可用的物理内存是不值得考虑的,您必须努力工作才能比系统现有的虚拟内存实现做得更好。其中一些系统试图使用所有可用的内存(例如"未使用的RAM是浪费的RAM")。
话虽如此,如果这些假设是正确的:通常最好只是减少分配大小和工作集,并根据需要自己进行I/O。
您的操作系统可能也使用磁盘缓存;对于大块内存,读写速度可能比您想象的要快。
更深层:使用虚拟内存或内存映射文件来处理这些大型数据集。您的内核可能会很好地处理这些情况。
显然,我不会假设这种最坏的情况,并提前分配所有内存。
然后,您可能会惊讶地发现,在某些环境中,单独使用2 GB的calloc
可能比人们提出的其他替代方案更好,因为大型calloc
可以在虚拟内存中保留一个域,仅在您访问页面时加载/初始化页面。根据您的使用情况,这种方法将比您可能得到的一些替代方案要好得多。
在理解程序或输入的分配模式时,许多问题的一个好的起点是从保守开始,然后根据观察做出最有益的调整。在许多情况下,您只需要a)在需要调整大小时准确确定调整大小的程度b)在适当的情况下重用分配c)针对手头的问题设计好数据。