全局变量分配在数据段中,而局部变量则留在堆栈中。我知道访问存储在堆中的变量比访问局部变量要慢,但我不知道访问局部变量是否比访问全局变量快。它取决于编译器吗?差异是否显着?
2 回答
在继续阅读之前另请参阅这篇文章(我不是在谈论访问堆栈与堆):
架构和内存管理策略变化如此之大,以至于很难讨论。我将以 Intel x86 为例。
访问数据只需通过一条指令,无论我们在哪里访问。
<安装> <SEG> : <地址>
INST 代表我们正在执行的指令。SEG 代表我们正在访问的段。VADDR 代表虚拟地址。
在实模式下,SEG 是段的基地址,ADDR 是段的内部地址。在实模式下访问数据的效率似乎在每个段中是相同的。(无论栈、堆还是全局)
在保护模式下,SEG 为选择器,ADDR 为虚拟地址。最棘手的是,MMU(内存管理单元)开始工作并指责谁访问了“未预期”的数据。
当您访问的数据不在内存中时,MMU 会产生缺页中断并请求 OS 切换页面。并且 MMU 会通过花费更多时间与硬盘交换页面来责备您。
因此,不考虑数据是如何访问的,仅仅谈论访问全局数据或本地数据是否更快是徒劳的。
从我的角度来看,您更有可能访问堆栈“本地数据”而不是全局数据,因此访问全局数据时页面错误概率可能更高。
Stack 和 head 只是实现细节,这意味着它们可能依赖于编译环境。C 标准只定义了标识符的链接和存储时长。但你是对的,堆栈、堆和数据段是常见的实现。
但是当您说访问存储在堆中的变量比访问局部变量慢时,您就错了。分配和解除分配动态内存确实比使用自动变量更复杂并且花费更多时间,但是在它们的生命周期中,访问(无论是读取还是写入)的成本完全相同 - 至少在通用基础架构上是这样。会有所不同的是:
- 是处理器缓存或二级缓存中的数据(加速访问)
- 是当前交换页面中需要从磁盘重新加载的数据(减慢访问速度)
但是对于动态、自动或静态数据,两者都可能发生相同的情况......