数据段与堆栈

Fra*_*uro 2 c stack data-segment

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

Hao*_*Luo 5

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

访问堆中的数据是否比从堆栈中访问更快?

体系结构和内存管理策略千差万别,以至于很难讨论。我将以 Intel x86 为例。

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

<INST> <SEG> : <地址>

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

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

在保护模式下,SEG 将是一个选择器,而 ADDR 将是虚拟地址。最棘手的是,MMU(内存管理单元)开始工作并指责谁访问了“非预期”的数据。

当您访问的数据不在内存中时,MMU 会产生页面错误中断并请求操作系统切换页面。并且 MMU 通过花费更多时间与硬盘交换页面来责备您。

所以只谈全局数据访问速度快还是本地访问速度快,不考虑数据的访问方式是徒劳的。

从我的角度来看,您更可能访问堆栈“本地数据”而不是全局数据,因此访问全局数据时页面错误的概率可能更高。


Ser*_*sta 5

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

但是,当您说访问存储在堆中的变量比访问局部变量慢时,您就错了。分配和释放动态内存确实比使用自动变量更复杂并且需要更多时间,但在它们的生命周期中,访问(无论是读取还是写入)成本完全相同 - 至少在公共基础设施上是这样。造成不同的是:

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

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