抛弃std::allocator以支持自定义解决方案的一些真正好的理由是什么?您是否遇到过这样的情况:它对于正确性、性能、可伸缩性等来说是绝对必要的?有什么聪明的例子吗?
自定义分配器一直是标准库的一个特性,但我并不太需要它。我只是想知道是否有人能提供一些令人信服的例子来证明他们的存在。
抛弃std::allocator以支持自定义解决方案的一些真正好的理由是什么?您是否遇到过这样的情况:它对于正确性、性能、可伸缩性等来说是绝对必要的?有什么聪明的例子吗?
自定义分配器一直是标准库的一个特性,但我并不太需要它。我只是想知道是否有人能提供一些令人信服的例子来证明他们的存在。
当前回答
自定义分配器可以发挥作用的一个领域是游戏开发,特别是在游戏机上,因为它们只有少量内存,没有交换空间。在这样的系统上,您要确保对每个子系统都有严格的控制,这样一个不重要的系统就不能从一个重要的系统窃取内存。池分配器等其他功能可以帮助减少内存碎片。你可以在这里找到一篇关于这个主题的详细的长篇论文:
EASTL—Electronic Arts标准模板库
其他回答
一种基本情况:当编写必须跨模块(EXE/DLL)边界工作的代码时,必须保持分配和删除只发生在一个模块中。
我在Windows上的插件架构中遇到了这种情况。例如,如果你跨DLL边界传递一个std::string,任何字符串的重新分配都发生在它起源的堆中,而不是在DLL中的堆中,这可能是不同的*。
*实际上比这更复杂,如果你动态链接到CRT,这可能会工作。但是,如果每个DLL都有一个到CRT的静态链接,那么您将陷入痛苦的世界,在那里幻影分配错误不断发生。
我正在使用一个MySQL存储引擎,它的代码使用c++。我们使用一个自定义分配器来使用MySQL内存系统,而不是与MySQL竞争内存。它允许我们确保我们使用的内存是用户配置MySQL使用的内存,而不是“额外的”。
强制性链接到Andrei Alexandrescu 2015年CppCon关于分配者的演讲:
https://www.youtube.com/watch?v=LIb3L4vKZ7U
好处是,只是设计它们让你想到如何使用它们:-)
当使用gpu或其他协处理器时,以特殊的方式在主存中分配数据结构有时是有益的。这种特殊的内存分配方式可以在自定义分配器中以一种方便的方式实现。
在使用加速器时,通过加速器运行时进行自定义分配是有益的,原因如下:
through custom allocation the accelerator runtime or driver is notified of the memory block in addition the operating system can make sure that the allocated block of memory is page-locked (some call this pinned memory), that is, the virtual memory subsystem of the operating system may not move or remove the page within or from memory if 1. and 2. hold and a data transfer between a page-locked memory block and an accelerator is requested, the runtime can directly access the data in main memory since it knows where it is and it can be sure the operating system did not move/remove it this saves one memory copy that would occur with memory that was allocated in a non-page-locked way: the data has to be copied in main memory to a page-locked staging area from with the accelerator can initialize the data transfer (through DMA)
使用自定义分配器来使用内存池而不是堆可能会很有用。这只是众多例子中的一个。
对于大多数情况,这肯定是一个不成熟的优化。但它在某些情况下(嵌入式设备、游戏等)非常有用。