L1缓存命中的周期/成本与x86上的Register相比?

问题描述 投票:26回答:4

我记得在我的架构类中假设L1缓存命中是1个周期(即与寄存器访问时间相同),但在现代x86处理器上实际上是这样吗?

L1缓存命中多少个周期?它与寄存器访问相比如何?

performance x86 cpu-architecture cpu-cache micro-optimization
4个回答
35
投票

这是一篇关于这个主题的精彩文章:

http://arstechnica.com/gadgets/reviews/2002/07/caching.ars/1

要回答您的问题 - 是的,缓存命中与注册访问的成本大致相同。当然,高速缓存缺失是非常昂贵的;)

PS:

细节会有所不同,但这个链接有一些很好的大概数字:

Approximate cost to access various caches and main memory?

Core i7 Xeon 5500 Series Data Source Latency (approximate)
L1 CACHE hit, ~4 cycles
L2 CACHE hit, ~10 cycles
L3 CACHE hit, line unshared ~40 cycles
L3 CACHE hit, shared line in another core ~65 cycles
L3 CACHE hit, modified in another core ~75 cycles remote
L3 CACHE ~100-300 cycles
Local DRAM ~30 ns (~120 cycles)
Remote DRAM ~100 ns 

PPS:

这些数字表示更老,更慢的CPU,但比率基本上保持:

http://arstechnica.com/gadgets/reviews/2002/07/caching.ars/2

Level                    Access Time  Typical Size  Technology    Managed By
-----                    -----------  ------------  ---------     -----------
Registers                1-3 ns       ?1 KB          Custom CMOS  Compiler
Level 1 Cache (on-chip)  2-8 ns       8 KB-128 KB    SRAM         Hardware
Level 2 Cache (off-chip) 5-12 ns      0.5 MB - 8 MB  SRAM         Hardware
Main Memory              10-60 ns     64 MB - 1 GB   DRAM         Operating System
Hard Disk                3M - 10M ns  20 - 100 GB    Magnetic     Operating System/User

6
投票

没有。

单周期高速缓存延迟曾经是较低时钟速度的简单有序流水线上的事情(因此每个周期更加纳秒),特别是对于更简单的高速缓存(更小,不作为关联,并且对于没有的高速缓存具有更小的TLB)纯粹实际上解决了。)例如classic 5-stage RISC pipeline就像MIPS一样,在高速缓存命中时假定1个周期用于存储器访问,在WB阶段之前用EX中的地址计算和MEM中的存储器访问。

现代高性能CPU将流水线分成更多阶段,允许每个周期更短。这让像add / or / and这样的简单指令运行得非常快,仍然是1个周期的延迟但是时钟速度很高。


有关循环计数和乱序执行的更多详细信息,请参阅Agner Fog's microarch pdf以及x86 tag wiki中的其他链接。


英特尔Haswell的L1负载使用延迟是指针追逐的4个周期,这是现代x86 CPU的典型特征。即mov eax, [eax]在循环中运行的速度有多快,指针指向自身。 (或者对于在缓存中命中的链接列表,易于使用闭环进行微支撑)。另请参见Is there a penalty when base+offset is in a different page than the base?该4周期延迟特殊情况仅适用于指针直接来自另一个负载,否则为5个周期。

英特尔CPU中的SSE / AVX向量的负载使用延迟高1个周期。


存储重新加载延迟是5个周期,与缓存命中或未命中无关(它的存储转发,从存储缓冲区读取尚未提交到L1d缓存的存储数据)。

正如Harold评论的那样,寄存器访问是0个周期。所以,例如:

  • inc eax有1个周期延迟(只是ALU操作)
  • add dword [mem], 1有6个循环延迟,直到来自dword [mem]的负载准备就绪。 (ALU +存储转发)。例如在内存中保持循环计数器将循环限制为每6个循环一次迭代。
  • mov rax, [rsi]有4个循环延迟,从rsi准备到rax准备好在L1命中(L1负载使用延迟)。

http://www.7-cpu.com/cpu/Haswell.html有一个每个缓存的延迟表(我将在这里复制)和一些其他实验数字,包括L2-TLB命中延迟(在L1DTLB未命中)。

Intel i7-4770(Haswell),3.4 GHz(Turbo Boost off),22 nm。 RAM:32 GB(PC3-12800 cl11 cr2)。

  • L1数据缓存= 32 KB,64 B /线,8路。
  • L1指令高速缓存= 32 KB,64 B /线,8路。
  • L2缓存= 256 KB,64 B /线,8路
  • L3缓存= 8 MB,64 B /线
  • L1数据高速缓存延迟=通过指针进行简单访问的4个周期(mov rax, [rax]
  • L1数据高速缓存延迟=使用复杂地址计算(mov rax, [rsi + rax*8])进行访问的5个周期。
  • L2缓存延迟= 12个周期
  • L3缓存延迟= 36个周期
  • RAM延迟= 36个周期+ 57 ns

顶级基准页面是http://www.7-cpu.com/utils.html,但仍然没有真正解释不同的测试大小意味着什么,但代码是可用的。测试结果包括Skylake,在该测试中几乎与Haswell相同。

@ paulsm4的答案有一个多插槽Nehalem Xeon表,包括一些远程(其他插槽)内存/ L3号码。


1
投票

如果我没记错的话,大约需要1-2个时钟周期,但这是一个估计值,而较新的缓存可能会更快。这是我所拥有的计算机体系结构书籍,这是AMD的信息,因此英特尔可能会略有不同,但我会将它限制在5到15个时钟周期之间,这对我来说似乎是一个很好的估计。

编辑:哎呀L2是TAG访问的10个周期,L1需要1到2个周期,我的错误:\


0
投票

实际上,L1缓存命中的成本几乎与寄存器访问的成本相同。这对我来说是令人惊讶的,但这是事实,至少对于我的处理器(Athlon 64)而言。前段时间,我编写了一个简单的测试应用程序,用于对多处理器系统中共享数据访问的效率进行基准测试。应用程序主体是在预定义的时间段内递增的简单存储器变量。为了制作comapison,我首先对非共享变量进行了基准测试。在那次活动中我捕获了结果,但在应用程序反汇编时,我发现编译器欺骗了我的期望,并对我的代码应用了不必要的优化。它只是将变量放入CPU寄存器并在寄存器中迭代递增,而无需访问存储器。但是,在我强制编译器使用内存变量而不是寄存器变量之后,实际出现了惊喜。在更新的应用程序上,我获得了几乎相同的基准测试结果。性能下降实际上是疏忽的(约1-2%),看起来与某些副作用有关。

结果:

1)我认为您可以将L1缓存视为非托管处理器寄存器池。

2)通过强制编译器存储经常访问处理器寄存器中的数据,没有任何意义来应用残酷的组合优化。如果它们经常被频繁访问,它们将存在于L1高速缓存中,并且由于这将具有与处理器寄存器相同的访问成本。

© www.soinside.com 2019 - 2024. All rights reserved.