堆和栈中数据访问性能的比较

10
众所周知,对于大多数算法来说,在栈上分配和释放数据比在堆上执行要快得多,这是常识。在C++中,代码的差异就像:
double foo[n*n]

vs.

double* foo = new int[n*n]

但是,当访问和计算堆栈或堆中的数据时,是否有任何重要的区别?也就是说,速度上是否有差别?
foo[i]

该代码应该在几种不同的架构上运行,因此尝试和测量是不可行的。

如果有帮助的话,这里有一个简单的基准测试,它只是从一个大数组中读取并写入每个元素。在我的机器上,当数组在堆栈上时,它运行速度至少快5倍。 - Gumby The Green
4个回答

4

可能存在(高度依赖于系统)有关缓存局部性和读写未命中的问题。如果您在堆栈堆数据上运行程序,则可能会遇到更多的缓存未命中,这取决于您的缓存架构,而不是在堆栈的一个连续区域上完全运行它。这是由Andrew Appel(来自SML / NJ)和Zhong Shao撰写的一篇论文,他们研究了这个问题,因为堆栈/堆分配是实现函数式语言的一个主题:

http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.3778

他们发现一些写缺失的性能问题,但估计这些问题会通过缓存技术的进步得到解决。
因此,我猜测对于当代的桌面/服务器设备来说,除非您运行经过高度优化的、针对特定体系结构的代码,并沿着缓存行流式传输数据,否则您不会注意到堆栈和堆访问之间的任何差异。对于具有小缓存(如ARM/MIPS控制器)的设备,情况可能会有所不同,在这些设备上忽略缓存可能会产生明显的性能影响。

2

单独看这些语句,并没有什么影响。
没有更多上下文,很难作出判断。堆栈有一些微不足道的优势,但几乎在所有情况下都可以忽略不计。

  • 堆栈可能已经在缓存中了,而新分配的堆块可能还没有。然而,这只是首次执行的惩罚。对于大量数据,你无论如何都会使缓存失效。

  • 堆栈分配本身比堆分配便宜一些,因为分配较为简单。

  • 长期来说,堆的主要问题通常是碎片化,这是一种“累积成本”,(通常)不能归因于单个分配,但可能会显著增加进一步分配的成本。

至少测量这些效果是棘手的。

建议:性能并不是决定因素。可移植性和可扩展性建议除了非常小的数据量外,使用堆栈。


1

堆栈更频繁地在CPU缓存中,因此在某些(大多数?)情况下可能会更快。

但最精确的答案可能是:这取决于......


-1
除了分配之外,无论是基于堆栈还是基于堆的访问数据都不应该有明显的区别 - 毕竟它们最终都是内存。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接