访问全局数据是否比访问本地数据更快?

Is accessing global data faster than accessing local data?

问题更多是关于 DRAM 的工作原理。

(用 C 术语来说)如果我有一个本地(位于堆栈)变量和一个全局(静态或动态分配)变量,访问哪个会更快? 考虑到既没有缓存也没有放在寄存器中!

所以实际的问题是,检索靠近先前触摸区域的数据是否比检索完全不同位置的数据更快,例如,行地址和列地址与先前不同。

如果访问时间确实存在差异,为什么?

大体上没有区别。无论给定地址是在堆栈上还是堆上,DRAM 的工作方式都是一样的。在实践中,有几种情况下局部变量通常更快:

  • 堆栈的前几个字节实际上总是在缓存中,第一次访问静态变量时,它可能不会。
  • 编译器通常可以静态分析局部变量的生命周期并将其优化到寄存器中,从而完全消除内存访问,而全局变量通常必须加载和存储,因为程序的另一部分可能已经改变了它以前,以后可以参考。
  • 在许多体系结构中,访问相对于堆栈指针的内存位置的机器指令比访问任意静态地址的机器指令更有效。

使事情复杂化的是“local/global”可能不是您真正想要的区别。例如,许多语言都有像全局变量一样实现的“静态局部”变量,但在词法上是局部的,而“线程局部”变量在词法上是非局部的,但存储在堆栈中。而且,如果您通过引用将本地分配的变量传递到调用链的最深处,它最终会脱离缓存并表现得与全局变量完全一样。

所以问题是

whether it is faster to retrieve data that is close to previously touched area than to retrieve data that is in completely different place

答案是肯定的,它更快。

TL;DR: DRAM 有一个缓冲区(一个缓存,如果你愿意的话,虽然它不是真正的缓存)

原因是 DRAM 的工作原理。

  • 一个 SIMM is 1 or 2 ranks that consist of multiple DRAM chips(ICs)。
  • 每个IC由多个bank组成(字节行+row/column解码器+行缓冲区)

  • 如果 IC 编号为 0 到 K,第 0 组到 M,第 0 行到 [=34] =]N;
    然后行 (0, m, n), (1, m, n) ... ( K, m, n)构成一个内存页(连续地址的数据)。

  • (a common case) 如果给定的SIMM每列有8个IC,一个bank有1024列(每列是一个字节),一个内存页(或整个缓冲内存)是8KB大小.

话虽如此,如果您访问的地址与为同一存储区请求的最后一个地址位于同一内存页上,则只会使用列解码器,这比当地址在不同的页面上。注意:2 倍的差异仅与 DRAM 相关,与到达 CPU 的总时间无关,后者仍然 >100 毫秒。

还有很多细节要添加,但我一点也不精通。

P.S。这个话题没有被广泛讨论,以上所有内容只是对我从检查不太好的书面信息中有意义的内容的一个非常简短的概述。