欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

CPU缓存架构原理剖析与相关优化

程序员文章站 2022-05-26 23:53:33
...

一、cpu架构

CPU缓存架构原理剖析与相关优化

 

 

二、cpu从内存加载数据的流程

程序运行时从内存加载数据,先从离核心最近的一级缓存读取,如果有数据就直接返回,逐层读取,如果三级缓存中都没有数据,就会从内存中加载一段连续的内存数据,一次加载数据的大小根据cache line配置的大小,一般为64字节,并将加载的数据依次放入缓存中。linux系统可以通过以下命令查看

CPU缓存架构原理剖析与相关优化

 

三、cpu的三级缓存、内存读取效率

  • 以2.2Ghz频率的CPU为例,每个时钟周期大概是0.5纳秒

  • L1缓存分为两部分:数据缓存和指令缓存。

  • 离CPU越近的缓存,读取效率越高,存储容量越小,造价越高。

  • 缓存SRAM比内存DRAM的材质造价高,因此容量都比较小

加载涞源

消耗时钟周期数

大致时间换算

容量大小,可以通过命令查看,以本机配置为准

L1缓存

4-5个时钟周期

2纳秒-2.5纳秒

64K

L2缓存

约12个时钟周期

约6纳秒

1M

L3缓存

约30个时钟周期

15纳秒

35.75M

内存

约100时钟周期以上

约50纳秒

G单位量级

查看每级缓存大小的命令如下,linux。其中可以看到L1缓存为index0、index1分别为指令缓存和数据缓存

CPU缓存架构原理剖析与相关优化

 

四、cpu使用效率的指标、及其监控方法

  • 了解了cpu的底层实现,我们程序设计中要追求的就是,更好的利用cpu的缓存,来减少从内存取数据的低效率(当然相比磁盘io肯定是快很多的。

  •  在程序应用中,我们通常需要关注缓存命中率这个指标。

  • 监控方法:linux为例,查询cpu缓存无命中次数,和缓存请求次数,进行计算缓存命中率即可

   perf stat -e cache-references -e cache-misses 

 

五、了解了cpu底层实现,程序、代码设计可优化点

1.基于程序从内存获取数据时,每次不仅取回所需数据,还会根据配置的cache linde的大小例如64字节,加载一段连续的内存数据到缓存中的特点,我们代码中、程序设计中可以借鉴优化的点:

  • 在集合遍历的场景,可以使用有序的数组,因为数组在内存中时一段连续的空间

  • 另外对象字段尽量定义为占用字节小的类型,比如在int可以时,不使用long类型,这样一次可以加载更多的数据到缓存中

  • 开源的nginx在存储http请求头,域名服务器时,采用的域名服务hash表中,hash 表的bucket的大小设置为cpu核心缓存行的整数倍

  • 在同一个对象多个字段属性,可能会存在于同一个缓存行中,导致的伪共享问题,可以通过缓存行补齐,解决多线程高并发环境下缓存失效问题。java8提供了 contended注解

2.因为每次加载的缓存中的数据量大小为cache line配置的大小,因此设计的对象大小要设计成cache line的倍数。比如在为64的配置中,如果读取的数据是50个字节,则最坏情况下,需要两次从内存加载;当为70个字节时,最坏情况下需要三次内存读取,才能加载到缓存中。

     50字节最坏两两次读取内存

      CPU缓存架构原理剖析与相关优化

    70字节最坏三次读取内存

      CPU缓存架构原理剖析与相关优化

 3.cpu有分支预测的能力,在使用ifelse case when等循环判断的场景时,可以顺序访问,可以有效提高缓存命中