C 数据段与堆栈

C 数据段与堆栈,c,stack,data-segment,C,Stack,Data Segment,全局变量分配在数据段中,而局部变量保留在堆栈中。我知道访问存储在堆中的变量比访问局部变量慢,但我不知道访问局部变量是否比访问全局变量快。它依赖于编译器吗?差异是否显著?在阅读之前,请参阅本文(我不是说访问堆栈与访问堆): 体系结构和内存管理策略千差万别,很难讨论。我将以英特尔x86为例 无论我们在何处访问数据,都只需通过一条指令即可访问数据 : INST代表我们正在执行的指令。 SEG代表我们正在访问的段。 VADDR代表虚拟地址 在实模式下,SEG将是段的基址,ADDR将是段的内部地址。在实

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

在阅读之前,请参阅本文(我不是说访问堆栈与访问堆):

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

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

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

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

在保护模式下,SEG将是选择器,ADDR将是虚拟地址。而最棘手的事情是MMU(内存管理单元)开始工作,并指责访问数据的人“出乎意料”

当您正在访问的数据不在内存中时,MMU会生成页面错误中断,并请求操作系统切换页面。MMU指责你花更多的时间用硬盘交换页面

因此,仅仅谈论访问全球数据还是本地数据更快,而不考虑如何访问数据,这是徒劳的


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

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

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

  • 数据是在处理器缓存中还是在二级缓存中(加快访问速度)
  • 是当前交换的脱离页面中的数据,需要从磁盘重新加载(降低访问速度)

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

您的第一个问题是否正确取决于编译器和目标平台。如果存在任何差异,则可能无关紧要。堆栈、堆和数据段在同一内存中。操作系统可以调出指定的任何内容。那么,从一个内存地址读取数据的速度如何可能比从另一个内存地址读取数据的速度快呢?例如,访问使用malloc生成的向量要比访问堆栈中生成的向量慢,因为它是如何分配的……但一旦内存被分配(在堆栈上或通过malloc),访问内存也需要同样的时间。是的,我现在就拿到了,谢谢。但这是否意味着分配全局内存所用的时间与在堆栈中分配内存所用的时间完全相同?@FrancescoDiLauro:分配全局内存没有多大意义。即使是standard(6.2.4对象的存储持续时间)也说,全局对象具有静态存储持续时间,并且[它们的]生命周期是程序的整个执行过程。因此,它们是在启动时创建的,从不释放。