Caching 指令缓存的方式和位置?

Caching 指令缓存的方式和位置?,caching,hardware,cpu-architecture,cpu-cache,Caching,Hardware,Cpu Architecture,Cpu Cache,如果我要运行一个二进制可执行程序,那么所有的指令都必须存储在指令缓存中吗?指令缓存是一级、二级或三级CPU缓存中的一个位置,还是另一个实体?我不太清楚在运行可执行文件时会发生什么物理情况,希望您能讲清楚。这些指令将永久存储在大容量存储设备上的二进制可执行文件中。当程序被执行时,可执行文件的内容被加载到主存储器(RAM)中。一般来说,CPU和RAM之间的所有通信都通过缓存;可执行文件中包含的指令也是如此 缓存可能包含指令、数据或两者。对于Intel CPU,有两个L1缓存:L1d用于数据,L1i用

如果我要运行一个二进制可执行程序,那么所有的指令都必须存储在指令缓存中吗?指令缓存是一级、二级或三级CPU缓存中的一个位置,还是另一个实体?我不太清楚在运行可执行文件时会发生什么物理情况,希望您能讲清楚。

这些指令将永久存储在大容量存储设备上的二进制可执行文件中。当程序被执行时,可执行文件的内容被加载到主存储器(RAM)中。一般来说,CPU和RAM之间的所有通信都通过缓存;可执行文件中包含的指令也是如此

缓存可能包含指令、数据或两者。对于Intel CPU,有两个L1缓存:L1d用于数据,L1i用于指令;L2和L3是共享的。下图非常清楚地说明了这一点:


这是简单的答案。如果你想了解更多,有很多好的材料。Ulrich Drepper是一个很好的读取工具。

磁盘上的可执行文件是逻辑内存映射到新进程的虚拟地址空间中的

与通常的虚拟内存一样,如果数据实际上不在DRAM中(硬页面错误),或者如果数据确实在DRAM中,但HW页面表尚未“连接”该页面,则触摸可执行文件的4k页面可能会触发页面错误。每次重复运行时仍可能发生软页面错误,因为操作系统通常在连接页面表时“懒惰”,即使文件数据在内核的页面缓存中也是如此

(x86使用4KB虚拟内存页。这是一种常见的页大小,但其他一些ISA使用或可以使用其他页大小,如8k或16k。)

内核可以通过确保至少包含进程入口点的页面在进入用户空间之前从磁盘加载并连接来进行优化。否则,它将立即将页面错误返回到内核。e、 很早的Linux,比如0.11,就是这样工作的,作为开发过程中的一个“让它工作起来”的步骤,然后再把它做好


当数据位于DRAM中时,CPU通过L1i/L2/L3缓存进行代码提取,从而执行操作。这与数据加载完全相同,但通过一级I缓存而不是一级D缓存,假设机器具有拆分的一级缓存。缓存的外部级别(假设存在)几乎总是统一的。现代x86 CPU和其他高端芯片(如POWER)通常有3级缓存,通常L1i/d和L2是每核专用的,有一个大的共享L3。否则,您可能只有专用L1i/L1d和共享L2,或者在单核心系统中可能只有1或2级缓存

这些缓存在大多数CPU上的行大小为64字节(包括自P4/Core 2以来的所有x86 CPU)。缓存未命中不是故障,核心只需等待线路到达即可。如果仍有任何无序执行未完成,则在代码缓存未命中时仍可能发生。但除此之外,CPU将无所事事

(TLB未命中也是一件事。大多数ISA都有硬件页面漫游,这使其对软件透明,但iTLB未命中同样会暂停指令提取,离开CPU而不进行任何排队工作。因此,i-cache/i-TLB未命中甚至比数据缓存/d-TLB未命中更糟糕,其中未命中下未命中/未命中下命中以及无序执行,可以让一些有用的工作继续进行。)


在现代x86 CPU中,解码的指令被缓存在一个小的、非常快的“uop缓存”中,并将机器代码字节缓存在L1i缓存中

奔腾4没有L1i缓存,只有一个跟踪缓存,但效果不是很好。而且它没有足够的晶体管或功率预算来支持解码器在跟踪缓存未命中时快速构建跟踪。这是NetBurst微体系结构的几个主要缺点之一