据我所知,内存池是运行时前在堆栈上分配的块或多个内存块。
相比之下,据我理解,动态内存是从操作系统请求的,然后在运行时分配到堆上。
//编辑//
据我所知,内存池的目的是提供RAM的手动管理,其中内存必须被程序员跟踪和重用。
从理论上讲,这对性能是有利的,原因如下:
我对内存池的理解正确吗?如果是这样的话,为什么不经常使用内存池呢?
发布于 2017-05-30 06:20:35
似乎这个问题在premature optimisation. XY problem 和中被否决了。
您应该专注于编写清晰的代码,然后在必要时使用分析器来执行优化。
我对内存池的理解正确吗?
不完全是。
..。堆上..。 ..。在堆里..。
存储持续时间与池的概念是正交的;池可以分配给 any 的四个存储期限(它们是:静态、线程、自动和动态存储持续时间)。
C++标准不要求任何这些都进入堆栈或堆中;如果将所有这些都看作是在同一个地方进行处理,则可能会很有用。毕竟,--他们(通常)--都会上硅片!
..。分配..。在运行之前。
重要的是,多个对象的分配发生在这些对象被首次使用之前(或者至少少于这些对象的频率);这就省去了必须分别分配每个对象。我想这就是你所说的“运行前”的意思。在选择分配的大小时,您越接近任何给定时间所需的对象总数,过度分配造成的浪费就越少,过度调整所造成的浪费也就越少。
但是,如果你的操作系统不是史前的话,池的优势就会很快消失。如果您在进行优化之前和之后使用了分析器,您可能会看到这一点!
对于像Windows1.0这样简单的操作系统来说,情况可能是这样的。但是,在这一天,具有分配存储时间的对象通常存储在虚拟内存中,虚拟内存定期被写入磁盘并从磁盘读取(这称为分页)。因此,碎片内存可以被碎片化,更常用的对象、函数和方法甚至可能最终被合并到公共页面中。
也就是说,分页为您形成一个隐式池(和缓存预测)!
CPU可以比动态块更快地解析静态内存块。
虽然具有静态存储持续时间的对象通常位于堆栈上,但这并不是C++标准所要求的。在堆上分配静态内存块的地方,完全有可能存在C++实现。
动态对象上的缓存命中速度与对静态对象的缓存命中速度一样快。--碰巧堆栈通常保存在缓存中;您应该尝试在没有堆栈的情况下编程,这样您可能会发现缓存有更多的空间用于堆!
在优化之前,您应该始终使用分析器来度量最重要的瓶颈!然后您应该执行优化,然后再次运行分析器以确保优化成功!
这不是一个机器独立的过程!您需要对每个实现进行优化!pessimisation!对 one implementation 的优化很可能是对另一个的优化。
如果是这样的话,为什么不经常使用内存池呢?
上面描述的虚拟内存抽象,结合使用缓存分析器消除猜测工作,实际上消除了池在除最不知情的(即使用分析器)方案中的所有有用性。
发布于 2017-05-30 05:26:26
自定义分配器可以帮助性能,因为默认分配程序是针对特定用例进行优化的,而这种情况很少分配大量内存。
但是比方说,在一个模拟器或游戏中,你可能会有很多事情发生在一个框架中,经常分配和释放内存。在这种情况下,默认的分配器不那么好。
一个简单的解决方案可以是为帧中发生的所有丢弃的事情分配一个内存块。这个内存块可以一次又一次地被覆盖,删除可以推迟到以后的时间。游戏级别的结束或者其他什么的。
发布于 2017-05-30 06:51:42
内存池用于实现自定义分配器。
一个常用的是线性分配器。它只保留一个指针分隔分配/释放的内存。用它分配只是一个问题,增加指针的N个字节请求,并返回它的前一个值。取消分配是通过重置指向池开始的指针来完成的。
https://stackoverflow.com/questions/44253689
复制相似问题