数据段与堆栈

Data segment vs stack

一个全局变量分配在数据段,而一个局部变量留在栈中。我知道访问存储在堆中的变量比访问局部变量慢,但我不知道访问局部变量是否比访问全局变量快。它取决于编译器吗?差异是否显着?

在继续阅读之前另请参阅这篇文章(我不是在谈论访问堆栈与堆):

Is accessing data in the heap faster than from the stack?

体系结构和内存管理策略差异很大,很难讨论。我将以Intel x86为例。

无论我们在何处访问,都只需一条指令即可访问数据。

:

INST代表我们正在执行的指令。 SEG 代表我们正在访问的段。 而VADDR代表虚拟地址。

实模式下,SEG是段的基地址,ADDR是段的内部地址。在实模式下访问数据的效率似乎在每个段之间都是相同的。 (无论栈,堆,还是全局)

保护模式下,SEG为选择符,ADDR为虚拟地址。最棘手的是 MMU(内存管理单元)开始工作并指责谁访问数据 'not expected'。

当您正在访问的数据不在内存中时,MMU 会产生页面错误中断并请求OS 切换页面。 MMU 将更多时间与硬盘交换页面归咎于您。

所以不考虑数据的访问方式,光说访问全局数据快还是本地访问快,是徒劳的。

从我的角度来看,您访问堆栈'local data'的可能性比全局数据大,因此访问全局数据时页面错误概率可能更高。

Stack 和head 只是实现细节,这意味着它们可能取决于编译环境。 C标准只定义了标识符的链接和存储期限。但是你是对的,栈,堆和数据段是常见的实现。

但是当你说访问存储在堆中的变量比访问局部变量慢时,你错了。 分配和解除分配动态内存确实比使用自动变量更复杂并且花费更多时间,但是在它们的生命周期中,访问(无论是读取还是写作)的成本完全相同——至少在公共基础设施上是这样。不同之处在于:

  • 是处理器缓存或二级缓存(加速访问)中的数据
  • 当前换出页面中的数据需要从磁盘重新加载(减慢访问速度)

但对于动态、自动或静态数据,两者都可能发生相同的情况...