<分区>
我想知道 realloc() 的实际性能成本是多少:我经常这样做以将可用内存区域扩展一个元素(=特定结构)。是 - 感谢 MMU - 这样的 realloc() 只是保留内存区域的扩展,还是在某些条件下可以想象到的所有数据的完整复制?
据我所知,当 std::vector 的大小增加并且预定义的内存量太小时,它经常必须复制内存区域......
标签 c++ c performance malloc realloc
<分区>
我想知道 realloc() 的实际性能成本是多少:我经常这样做以将可用内存区域扩展一个元素(=特定结构)。是 - 感谢 MMU - 这样的 realloc() 只是保留内存区域的扩展,还是在某些条件下可以想象到的所有数据的完整复制?
据我所知,当 std::vector 的大小增加并且预定义的内存量太小时,它经常必须复制内存区域......
最佳答案
realloc
复制所有数据。假设其他任何事情都只是在寻求性能问题。 realloc
可以避免复制的情况很少,您绝对不应该指望它们。我见过不止一种 realloc
的实现,它们甚至不屑于实现代码来避免复制,因为这样做不值得付出努力。
MMU 与它无关,因为重新映射支持分配的内存页面的成本在您命中超过两个页面之前不会得到返回。这是基于我 15 年前阅读的研究,从那时起,内存复制变得更快,而内存管理由于 MP 系统而变得更加昂贵。这也仅适用于内核内部的零拷贝方案,没有传递系统调用开销,这很重要并且会在这里减慢速度。它还要求您的分配完全对齐和调整大小,从而进一步降低以这种方式实现 realloc
的有用性。
如果未分配要扩展到的内存块,realloc
最多可以避免复制数据。如果 realloc
是您的应用程序唯一做的事情,您可能会很幸运,但只要有一点碎片或其他分配的东西,您就倒霉了。始终假设 realloc 是 malloc(new_size); memcpy(新的,旧的,old_size);免费(旧);
。
在使用 realloc
调整数组大小时,一个好的做法是跟踪数组中有多少元素并具有单独的容量。仅当元素数量达到容量时才增加容量并重新分配
。在每个 realloc 上将容量增加 1.5 倍(大多数人做 2 倍,这在文献中经常被推荐,但研究表明 2 倍会导致非常糟糕的内存碎片问题,而 1.5 倍几乎同样有效并且对内存更好)。像这样:
if (a->sz == a->cap) {
size_t ncap = a->cap ? a->cap + a->cap / 2 : INITIAL_CAP;
void *n = realloc(a->a, ncap * sizeof(*a->a));
if (n == NULL)
deal_with_the_error();
a->a = n;
a->cap = ncap;
}
a->a[a->sz++] = new_element;
如果包含数组的结构是零初始化的,这甚至适用于初始分配。
关于c++ - realloc() 的性能消耗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39449050/