堆栈、缓存缺失和虚拟内存

stack, cache misses and virtual memory

本文关键字:虚拟内存 缓存 堆栈      更新时间:2023-10-16

一般来说,对于我所记得的程序的stack,它是以特殊方式处理的内存的特殊部分(通过LIFO结构即'堆栈'的方式)。

我在Linux中使用C和c++工作,我不确定以下几点

  1. 作为堆栈一块通用内存,这是否意味着在Linux进程中它应该在该进程的虚拟内存的某些页面中?

  2. 我习惯于知道,如果一块内存(我总是只考虑堆)驻留在L1缓存中,将比L3缓存更快地检索。它也适用于堆栈吗?

现在堆栈通常比堆快,但如果第2点为真,仍然有一些来自堆栈的数据可能在L3行,并在系统中引入缓慢。

我在下列条件下的推理是正确的还是我错过了什么?

这是特定于处理器的:AMD和英特尔在做不同的事情,甚至在每个品牌内都是特定于型号的。

一些处理器(我忘记了,可能是旧的AMD)将堆栈机器指令(即PUSH, POP, RETCALL等…)与L1缓存相关。

顺便说一句,Andrew Appel(在上个世纪)写道,垃圾收集可以比堆栈分配更快(对于使用CPS技术编译的SML),但是,IIRC,这在今天是不太正确的,因为当前的处理器有一些将调用堆栈与缓存相关的行为。

但是我相信调用堆栈的热点部分通常在L1缓存中(即使没有硬件帮助),因为那里的数据(局部变量,返回地址,…)经常被访问。

当然,调用堆栈在虚拟内存中;使用过程(5),例如:try

 tail /proc/$$/maps

(您可以使用cat而不是tail)可能获得:

7f6366db5000-7f6366dd5000 r-xp 00000000 08:11 2100860                    /lib/x86_64-linux-gnu/ld-2.19.so
7f6366fac000-7f6366fb0000 rw-p 00000000 00:00 0 
7f6366fcc000-7f6366fd3000 r--s 00000000 08:11 964796                     /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
7f6366fd3000-7f6366fd5000 rw-p 00000000 00:00 0 
7f6366fd5000-7f6366fd6000 r--p 00020000 08:11 2100860                    /lib/x86_64-linux-gnu/ld-2.19.so
7f6366fd6000-7f6366fd7000 rw-p 00021000 08:11 2100860                    /lib/x86_64-linux-gnu/ld-2.19.so
7f6366fd7000-7f6366fd8000 rw-p 00000000 00:00 0 
7fff59aa1000-7fff59ac2000 rw-p 00000000 00:00 0                          [stack]
7fff59bfe000-7fff59c00000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

注意[stack]段。

请阅读有关ASLR &vdso (7)

根据定义(CPU缓存),L1缓存通常包含最常访问的数据。缓存缺失代价很高(访问RAM棒中的数据可能比访问L1缓存慢100倍)。