Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 内存池:它们会提高大于缓存线大小的结构的缓存使用率吗?_C++_Caching - Fatal编程技术网

C++ 内存池:它们会提高大于缓存线大小的结构的缓存使用率吗?

C++ 内存池:它们会提高大于缓存线大小的结构的缓存使用率吗?,c++,caching,C++,Caching,据我所知,如果对象小于缓存线大小,内存池应该可以提高通常一起访问的对象的缓存性能,因为这样相邻的对象可能会同时被提取到缓存中 但是对于大于缓存线大小的对象呢?将这些数据汇集到同一内存区域有什么好处吗 (假设分配/解除分配时间微不足道,我担心的是访问…) 谢谢 使用池的一个重要原因是它们比通用分配器的分配方案简单得多。由于所有对象都具有相同的大小,因此没有碎片,您只需要维护一个空闲列表。对于新的分配,您尝试从空闲列表的顶部弹出,或者如果列表为空,则增加高水位线,完成。(您可以在池内存本身的O(1)

据我所知,如果对象小于缓存线大小,内存池应该可以提高通常一起访问的对象的缓存性能,因为这样相邻的对象可能会同时被提取到缓存中

但是对于大于缓存线大小的对象呢?将这些数据汇集到同一内存区域有什么好处吗

(假设分配/解除分配时间微不足道,我担心的是访问…)


谢谢

使用池的一个重要原因是它们比通用分配器的分配方案简单得多。由于所有对象都具有相同的大小,因此没有碎片,您只需要维护一个空闲列表。对于新的分配,您尝试从空闲列表的顶部弹出,或者如果列表为空,则增加高水位线,完成。(您可以在池内存本身的O(1)空间中实现空闲列表。)


然而,池的使用是高度情景化的,是否有任何好处在很大程度上取决于您的实际代码路径和分配需求。现代标准分配器已经非常适用于许多短期固定大小的分配,因此您确实需要对其进行分析和检查。

我以前的项目是一个嵌入式应用程序,带有用于ARM SAM9x平台的内置webserver。它只有64K堆,没有任何控制台/显示器或文件系统,因此无法将错误打印到stderr或将其记录到文件中。尽管如此,它必须在7/24小时内工作。它不应该因为“内存不足”错误而停止,它必须在没有错误的情况下运行。如果它只启动一次,它永远不会停止。内存不足不是可恢复的错误,而是系统完全失败

因此,我决定不使用新的。我曾经使用过对象数组:环形缓冲区、固定大小的池等等,而且它很有效。Java(和C#等)让我们错了,这些现代语言说,内存是一个巨大的海洋,任何人都可以从中汲取。是的,这是真的,如果你有很多,但是成本很高,就像你在这篇文章中提到的


试试看!尽可能少地使用new(当然还有malloc())。一个很好的副作用:你不必使用delete(和free()),就不会有内存泄漏问题。

如果你的应用程序使用了大量内存并开始交换,那么内存池是有意义的。然后,如果对象彼此相邻,它们将一起被分页进出。

这不是对他的问题的回答。问题是关于内存分配优化,我只是添加了另一种方法。这不是关于内存分配优化,而是关于内存访问优化,这是一个完全不同的问题,即使它可以通过特定的分配规则获得。在C++中,你可以实现<代码>运算符new <代码>,甚至是按类的基础。因此,使用“固定大小池”并不意味着您必须放弃
new
。此外,即使使用固定大小的池,也必须使用
delete
或等效工具。毕竟,必须将未使用的内存返回到池中,否则它会很快耗尽。这是C++中不使用新的/删除的编程风格。在编译时分配所有对象。这是一种绕池的问题。在这种方法工作的地方有很多问题——还有一些问题,如果不在运行时分配对象,您将无法生存。在您考虑池或自己的分配器之前,请选中此选项。您指的是缓存线大小。大多数系统都有具有不同缓存线大小的多级缓存。此外,主存是按页组织的,未被主动访问的页会稍微断电。也就是说,即使是主内存也能从引用的局部性中受益。我将这一点标记为确定的——虽然Kerrick的答案是正确的,但它实际上是关于分配/解除分配的,这并不困扰我。MSalters的评论也是相关的。但总的来说,我得出的结论是,在这里突出显示的情况下,访问速度只会显著加快。作为脚注,我确实发现了池的另一个用途:它们意味着指针倾向于按地址的严格递增顺序分配。这大大加快了我的一个例程的速度,该例程构建了一个由指针索引的大型stl::对象集,然后可以使用堆插入提示。(对象也由另一个字段索引,但在堆创建时,所有对象的索引恰好相等)。