【问题标题】:Is the stack in a cache?堆栈是否在缓存中?
【发布时间】:2016-10-11 11:34:40
【问题描述】:

在现代计算机中,我知道当前代码区域位于高速缓存中。但是,在许多计算机语言实现中,本地(自动)变量将位于堆栈上,因此会有很多对堆栈的内存访问。

普通架构中的堆栈是否在另一个缓存中?

如果不是,假设堆栈可以重新定位为“本地”,即非常靠近当前代码段,因此它将位于用于代码的高速缓存内。这会加快自动变量的内存访问速度吗?

【问题讨论】:

  • 它几乎是自动的,堆栈内存具有非常好的引用局部性并且被大量访问所以它总是在一级缓存中。在许多语言实现中,局部变量在堆栈帧上,而是经过优化以存储在处理器寄存器中。哪个是最快的可用内存。
  • @HansPassant 在 32 位模式的 i7 处理器上,有 8 个寄存器,其中 6 个可用于本地。由于在大多数情况下,交换和实用程序需要至少 1 个寄存器,因此您通常不会获得超过 5 个用于本地的寄存器。因此,如果您的函数有超过 5x4 (20) 字节的变量,那么您将使用堆栈来存储变量。 double 需要 8 个字节的存储空间,几乎从不作为寄存器变量实现。所以每一个双打都会在记忆中。在我编写的那种程序中,函数通常会有十几个双精度数。
  • 现在已经不是 1978 年了。 double 将存储在 XMM 寄存器或 FPU 堆栈中。
  • @HansPassant 我不知道您正在使用什么超级计算机,但是当我对我的代码进行反汇编时,我的大部分变量都位于 EBP 偏移处,这意味着它们在堆栈上。
  • 堆栈就是内存。处理器不知道内存访问是否是堆栈。

标签: performance caching memory stack


【解决方案1】:

大多数现代计算机会不加选择地缓存内存,因此 CPU 访问的任何内存都会被缓存。因此,这包括包括堆栈在内的内存。事实上,堆栈很可能几乎一直被缓存,因为它被频繁访问。

对堆栈进行缓存的主要问题是,由于它被频繁修改,它可能导致缓存与主内存不同步并触发缓存未命中,从而损害性能。这通常不会发生,因为大多数架构使用所谓的回写缓存,这意味着每个缓存块,称为缓存行,都有一个脏位并使用延迟需要时将缓存复制回主存。这通常会导致相对较少的主内存更新,并且性能会很好。

但是,如果两个不同的线程尝试写入同一内​​存,则可能会出现性能问题。这可能会导致一致性缺失,从而导致缓存写入和更新到内存并降低性能。通常,软件的结构不会使两个不同的线程使用相同的堆栈。但是,如果发生这种情况,那么某些架构上的性能可能会很差,因为不同线程的堆栈访问冲突会导致频繁的缓存未命中。

【讨论】:

    【解决方案2】:

    实际上,当您将一个值从 CPU 寄存器压入堆栈时,该值将首先被缓存在一个隐藏寄存器中。这是可能的,因为现代 CPU(至少可以追溯到 15 年前)的寄存器多于寄存器名称,因此可以使用未命名的寄存器。

    【讨论】:

      猜你喜欢
      • 2021-06-28
      • 2018-04-21
      • 1970-01-01
      • 2013-12-06
      • 2012-04-17
      • 1970-01-01
      • 1970-01-01
      • 2021-01-25
      • 1970-01-01
      相关资源
      最近更新 更多