访问堆与堆栈对象的C ++性能

时间:2015-07-01 21:11:04

标签: c++ stack heap

我知道使用堆对象因为必要的内存管理(分配,释放)而变慢。访问它们怎么样?访问堆栈与堆上的对象时是否存在性能差异?

编辑:我的问题是not about allocation但访问它们。这包括堆栈与堆的内存位置,缓存未命中或我不知道的任何其他变量。用一个简单的玩具例子:

int stack_array[100];
int* heap_array = new int[100];
...
...
std::cout << stack_array[51]; // Any difference between these two statements
std::cout << heap_array[51]; // Any difference between these two statements

1 个答案:

答案 0 :(得分:2)

除非物理内存不同,否则您可能无法注意到堆栈和堆(动态内存)之间的速度差异。

无论内存位置如何,对数组的访问都是直接的。您可以通过查看编译器生成的汇编语言来确认这一点。

如果操作系统决定为您的阵列使用虚拟内存,则可能会有所不同。这意味着操作系统可以将数组中的数据块添加到硬盘驱动器中,并根据需要进行交换。

在大多数应用中,如果存储器类型之间存在物理差异(就速度而言),则可以忽略不计,以纳秒为单位。对于计算量更大的应用程序(大量数据或速度需求),这可能会有所不同。

但是,还有其他问题使内存访问成为非问题,例如:

  • 磁盘I / O
  • 等待用户输入
  • 内存分页
  • 与其他应用程序或线程共享CPU

所有上述项目的开销通常比访问存储设备的开销高出一个数量级。

使用动态内存而不是基于堆栈的主要原因是大小。堆栈内存主要用于传递参数和存储返回地址。未声明为静态的局部变量也将放置在堆栈中。大多数编程环境使堆栈区域的尺寸更小。较大的项可以放在堆上或声明为静态(并放在与globals相同的区域)。

担心正确性而非内存性能。有疑问时的档案。

编辑1:缓存未命中
缓存未命中是处理器在其数据缓存中查找并且找不到该项目的时间;然后,处理器必须从外部存储器中获取该项(例如,重新加载缓存)。

对于大多数应用程序,缓存未命中的性能可忽略不计,通常以小纳秒值测量。除非您的程序是计算密集型或处理大量数据,否则它们不会引人注意。

分支指令将比缓存未命中占用更多的执行时间。一些条件分支指令可能强制处理器重新加载指令流水线并重新加载程序计数器寄存器。 (注意:某些处理器可以将可执行循环代码拖入指令缓存并减少分支效果的损失。)

您可以整理数据以减少缓存未命中数。在网络上搜索&#34;数据驱动&#34;或者&#34;数据优化&#34;。还可以尝试通过应用代数,布尔代数和从循环中分解不变量来减少分支。