堆上分配的数据是否比堆栈上分配的数据更慢?

时间:2017-11-25 14:51:55

标签: c++ performance memory

我听说过有关此事的相互矛盾的意见。

有人说访问堆上分配的数据(即std::vector或通过malloc分配的动态数组)总是比访问堆栈上分配的数据慢一点,因为进程必须始终通过访问该数据的中间指针,该数据可能位于完全不同的存储区域;另一方面,他们维护,访问堆栈上分配的数据不需要通过这个中间指针,这个数据可能已经被缓存。

其他人声称只有堆上的数据分配比堆栈上的速度慢(因为mallocmmap和类似功能的开销),但访问不是,除了罕见的堆栈和堆位于不同物理驱动器上的情况。

真相是什么?

2 个答案:

答案 0 :(得分:2)

事实(至少在大多数现代cpus上)是堆栈和堆都执行相同,因为它们都只是RAM的一部分。所以取消引用指针几乎是一样的。

不同之处在于堆栈是为您的进程/线程预先分配的,因此您不需要mallocfree系统调用来处理它。特别是malloc代价高昂。另一个区别是可能有一些特定的CPU指令用于处理堆栈以提高性能(例如汇编pushpop)。然而,这些与内存访问(如将内存加载到寄存器)本身无关。

另一个不同之处在于,如果你用完了你的程序,你的程序就会崩溃。如果你用完了堆,那么你的操作系统可能会使用swap来减少数千次的性能。

缓存未命中当然是一个因素,它将更多地发生在堆上然后堆栈上。但这只是因为堆栈与堆栈相比非常大。但请注意,除非你编写极其繁重的cpu代码,否则缓存未命中并不是那么重要。

现在你是对的,std::vector必须取消引用额外的时间。但是这里的缓慢是取消引用,而不是堆栈或堆上的那些指针。它们在哪里并不重要。双重解除引用总是慢于单一。

现在,堆栈和堆也可​​能位于不同的物理设备上。并且这两个设备具有不同的速度(可能堆更快)。但这与堆栈和堆本身无关。这可能发生在内存的任何两个部分。你无法做任何事情。甚至操作系统都没有(好吧,也许它可以,我不确定)。这是主板的事情。此外,无论如何,主板很可能会为更快的设备提供支持。

答案 1 :(得分:0)

  

有人说访问堆上分配的数据(即std :: vector或通过malloc分配的动态数组)总是比访问堆栈上分配的数据慢一点,因为进程必须经过一个中间指针来访问数据,可能位于完全不同的记忆区域;另一方面,他们维护,访问堆栈上分配的数据不需要通过这个中间指针,这个数据可能已经被缓存。

这是牛粪废物。只有静态才能在没有中间指针寄存器的情况下访问堆栈数据是通过寄存器(SP)访问的,其中一些处理器具有补充堆栈寄存器(例如,BP,AP)。

另外,内存是内存是内存。使内存成为堆栈的唯一想法是它作为堆栈访问。

  

其他人声称只有堆上的数据分配比堆栈上的速度慢(因为malloc,mmap和类似函数的开销),但访问不是

这是对的。在堆栈上分配数据只需要一条指令。