realloc()的性能消耗
Perfomance-consumption of realloc()
我想知道realloc((实际需要多少性能:我经常这样做是为了将可用内存区域扩展一个元素(=特定结构(。多亏了MMU,这样的realloc((只是保留内存区域的扩展吗?还是在某些条件下可以完全复制所有数据?
据我所知,当std::vector的大小增加并且预定义的内存量太小时,它经常不得不复制内存区域。。。
realloc
复制所有数据。假设其他任何事情都只是在要求性能问题。realloc
可以避免复制的情况很少,绝对不应该指望它们。我见过不止一个realloc
的实现,它甚至不需要实现代码来避免复制,因为这不值得付出努力。
MMU与此无关,因为重新映射支持分配的内存页面的成本直到达到两个以上页面才会得到回报。这是基于我15年前读到的研究,从那时起,内存复制变得更快,而由于MP系统,内存管理变得更加昂贵。这也适用于仅在内核内的零拷贝方案,而不传递系统调用开销,这是非常重要的,并且会降低速度。它还要求您的分配是完全一致的和适当的,这进一步降低了以这种方式实现realloc
的有用性。
如果realloc
将扩展到的内存块没有被分配,那么它最多可以避免复制数据。如果realloc
是你的应用程序唯一能做的事情,你可能会很幸运,但只要有一点碎片或其他分配的东西,你就没有运气了。始终假设realloc是malloc(new_size); memcpy(new, old, old_size); free(old);
。
使用realloc
调整数组大小时,一个好的做法是跟踪数组中有多少元素并具有单独的容量。只有当元素数量达到容量时,才增加容量和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;
如果包含数组的结构是零初始化的,那么即使对于初始分配,这也有效。
复制数据并不是代价高昂的部分(尽管有些人可能不同意(。命中嵌入的malloc和free是昂贵的,并且可能会占用几乎所有的执行时间,这取决于您正在做的其他事情。如果是这样的话,修复它应该会给你一个大的加速。
这是我如何判断事物所花费的时间的分数。
最简单的解决方案是少做一次。当您分配一个数组时,请将其分配得特别大,然后自己跟踪实际使用了多少。
行为实际上取决于实现。但所有这些都试图将重新定位内存的成本降至最低。因为搬迁对性能来说非常昂贵。它对缓存有直接影响。我没有号码,但这是一项非常昂贵的手术
例如,在重新定位的情况下,如果运行时面临重新定位内存或扩展当前保留的内存的两个选项,则选择后者
但事情并不像我说的那么简单。它还必须考虑内存碎片
因此,有几个权衡需要满足
在您提到的vector
的情况下,它们使用不同的方案。如果vector
保留了m
字节,并且它需要额外的n
字节,则运行时将分配2 * (n+m)
以最大限度地减少将来重新定位的可能性。如果您超过了新的大小,下次它将使用4
而不是2
的因子;等等。我提到的数字不是真的
我对实现不是很感兴趣,希望其他人能给你更多具体的信息。
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- OpenMP阵列性能较差
- 递归列出所有目录中的C++与Python与Ruby的性能
- 大小相等但成员数量不同的结构之间的性能差异
- 为什么constexpr的性能比正常表达式差
- 在类中使用随机生成器时出现性能问题
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 海湾合作委员会 ARM 性能下降
- GCC 和 Clang 代码性能的巨大差异
- 在容量内调整矢量大小时的性能影响
- 了解算法的性能差异(如果以不同的编程语言实现)
- 未达到的情况会影响开关外壳性能
- QStringList vs list<shared_ptr<QString>> 性能比较C++
- 是否总是可以将使用递归编写的程序重写为不使用递归的程序C++,性能观点是什么?
- 哪种方法更好,性能明智
- C++ 特征库:引用的性能开销<>
- 与多个 for 循环与单个 for 循环 wrt 相关的性能从多映射获取数据
- 基于范围的 for 循环range_declaration中各种说明符之间的性能差异
- std::p mr::memory_resource 如何与 std::container 产生性能差异?
- realloc()的性能消耗