繁体   English   中英

不能足够快地分配内存?

[英]cannot allocate memory fast enough?

假设您的任务是解决应用程序中的性能瓶颈问题。 通过分析,我们发现瓶颈与内存分配有关。 我们发现,无论我们分配多少内存线程,应用程序每秒只能执行N个内存分配。 为什么我们会看到这种行为,以及我们如何提高应用程序分配内存的速率。 (假设我们无法更改正在分配的内存块的大小。假设我们无法减少动态分配内存的使用。)

好的,存在一些解决方案 - 但是几乎所有解决方案似乎都是通过某种约束或其他约束来排除的。

1.有更多线程分配内存

我们发现,无论我们分配多少内存线程,应用程序每秒只能执行N个内存分配。

从这里,我们可以交叉任何添加更多线程的想法(因为“无论有多少线程”......)。

2.一次分配更多内存

假设我们无法更改正在分配的内存块的大小。

显然,我们必须分配相同的块大小。

3.使用(某些)静态内存

假设我们不能减少动态分配内存的使用。

这个我觉得最有趣的一点。提醒我一个关于FORTRAN程序员的故事(在Fortran进行动态内存分配之前),他刚刚在堆栈上使用了一个巨大的静态数组作为私有堆。 不幸的是,这种约束使我们无法使用这样的技巧。但是,它确实可以解决(解决方案)的一个方面。


我的解决方案

在开始执行时(无论是计划的,或在每个线程的基础上)做出几个^内存分配系统调用。 然后在程序中使用稍后的内存(以及现有的动态内存分配)。

* 注意: '几个'可能是一个确切的数字, 由您的分析确定,问题在开头提到

TL; DR

关键是要修改的存储器分配的定时

...无论我们分配多少内存线程,应用程序每秒只能执行N次内存分配。 为什么我们会看到这种行为,以及我们如何提高应用程序分配内存的速率。

恕我直言,最可能的原因是分配来自一个共同的系统池。

因为它们共享一个池,所以每个线程都必须通过一些关键的段阻塞机制(可能是一个信号量)来访问它。

竞争动态内存的线程越多(即使用new)将导致更多关键的段阻塞。

任务之间的上下文切换是浪费时间。


如何提高利率?

选项1 - 序列化使用...当然,这意味着您不能简单地尝试在另一个级别使用信号量。 对于我工作的一个系统,在系统启动期间发生了高动态内存利用率。 在这种情况下,最简单的方法是更改​​启动,使线程n + 1(此集合)仅在线程n完成初始化并进入等待输入循环后才开始。 只有一个线程一次启动它,(并且很少有其他动态内存用户在运行)没有发生关键部分阻塞。 4个同步启动需要30秒。 4个序列化的启动在5秒内完成。

选项2 - 为每个特定线程提供ram池和私有new / delete。 如果一次只有一个线程访问池,则不需要临界区或信号量。 在嵌入式系统中,这里的挑战是为线程分配合理数量的私有池而不是浪费太多。 在具有数GB的ram的桌面上,这可能不是一个问题。

看起来像一个具有挑战性的问题,虽然没有细节,但你只能做一些猜测。 (这很可能是这个问题的想法)

这里的限制是分配数量,而不是分配的大小。 如果我们可以假设您可以控制分配的位置,则可以一次为多个实例分配内存。 请将以下代码视为伪代码,因为它仅用于说明目的。

const static size_t NR_COMBINED_ALLOCATIONS = 16;
auto memoryBuffer = malloc(size_of(MyClass)*NR_COMBINED_ALLOCATIONS);
size_t nextIndex = 0;
// Some looping code
    auto myNewClass = new(memoryBuffer[nextIndex++]) MyClass;
    // Some code
    myNewClass->~MyClass();
free(memoryBuffer);

尽管你最有可能解决这个瓶颈问题,但你的代码很可能变得更加复杂。 如果你必须返回这个新类,你甚至需要更多的代码来进行内存管理。

根据这些信息,您可以为STL编写自己的分配器实现,覆盖'new'和'delete'运算符......

如果这还不够,请尝试挑战限制。 为什么你只能进行固定数量的分配,这是因为独特的锁定? 如果是这样,我们可以改善吗? 为什么需要那么多的分配,改变正在使用的算法来解决这个问题......

我相信你可以使用一个可以负责内存分配的独立线程。 该线程将具有包含线程标识符映射和所需内存分配的队列。 线程不会直接分配内存,而是向队列发送分配请求并进入等待状态。 该队列将尝试从队列中处理每个请求的内存分配并唤醒相应的休眠线程。 当负责内存处理的线程由于限制而无法处理分配时,它应该等到可以再次分配内存。

可以在解决方案中构建另一层,因为@ Tersosauros的解决方案建议稍微优化速度,但它应该基于类似于上述想法的东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM