基础|01|CPU缓存知识(待完善0.3)

news/2025/3/15 16:21:22/

(写在前面,本文还没写完,争取在2022.2.1前写完,觉得可以的话,可以先关注噢)

概览

由于各存储结构的速度不同,容量和价格上也不同,因此

1、对于单个CPU产生了缓存架构

既然有了缓存,那么在多核中,怎么解决高速缓存一致性?

2、缓存一致性

MESI协议 确保了缓存一致性,该类型协议保证了多CPU的缓存之间同步

但该协议存在一些性能上的问题,因此,便有了Store buffer 机制,但Store buffer并不能保证变量写入缓存和主存的顺序 。

3、便有了内存屏障,该技术规定了一些操作必须在某些操作之后。

一、CPU缓存架构

各存储结构的速度比较

缓存物理架构

CPU读取存储器数据过程

1、CPU要取寄存器X的值,只需要一步:直接读取。

2、CPU要取L1 cachel的某个值,需要1-3步(或者更多):把cache:行锁住,把某个数据拿来,解

锁,如果没锁住就慢了。

3、CPU要取L2 cachel的某个值,先要到L1 cache里取,L1当中不存在,在L2里,L2开始加锁,加

锁以后,把L2里的数据复制到L1,再执行读L1的过程,上面的3步,再解锁。

4、CPU取L3 cachel的也是一样,只不过先由L3复制到L2,从L2复制到L1,从L1到CPU。

5、CPU取内存则最复杂:通知内存控制器占用总线带宽,通知内存加锁,发起内存读请求,等待

回应,回应数据保存到L3(如果没有就到L2),再从L3/2到L1,再从L1到CPU,之后解除总线锁

定。

寄存器并不每次数据都可以从缓存中取得数据,万一不是同一个内存地址中的数据,那寄存器还必须直接绕过缓存从内存中取数据。所以并不每次都得到缓存中取数据,这种现象有个专业的名称叫做缓存的命中率


二、缓存相关概念

缓存行

cache line 是缓存进行管理的一个最小存储单元,也叫缓存块。从内存向缓存加载数据也是按缓存块进行加载的,一个缓存块和一个内存中相同容量的数据块(下称内存块)对应。

缓存行大小通常为64byte。缓存行是什么意思呢?比如你的L1缓存大小是512kb,而cacheline=64byte,那么就是L1里有512*1024/64个cacheline

底层对于缓存行的管理存在很多方式,因为太过底层,先不记录,详细参考14 | CPU Cache:访存速度是如何大幅提升的?-极客时间

程序局部性

局部性是虚拟内存的基础,在程序运行时,可只装入部分程序的内存。局部性主要分为时间局部性和空间局部性,空间局部性简单来说就是在程序的一个存储位置被引用,那么其附近的位置也将被引用;

因此,在缓存结构中,通常会加载临近的内存都到缓存中(具体怎么加载?),也正因此,下面代码会存在一些性能上的差异

详细分析见 14 | CPU Cache:访存速度是如何大幅提升的?-极客时间

/**
当按行访问时地址是连续的,下次访问的元素和当前大概率在同一个 cache line
(一个元素 8 字节,而一个 cache line 可以容纳 8 个元素),
但是当按列访问时,由于地址跨度大,下次访问的元素基本不可能还在同一个 cache line,
因此就会增加 cache line 被替换的次数,所以性能劣化。
*/
a = new long[1024*1024][6];
//省略初始化过程
for(int i = 0; i < 1024*1024; i++) {   for(int j = 0; j < 6; j++) {   // 按行相加a[i][j]++;     } 
} for(int j = 0; j < 6; j++) {   for(int i = 0; i < 1024*1024; i++) {   //按列相加a[i][j]++;     } 
} 

伪共享

伪共享(false-sharing)的意思是说,当两个线程同时各自修改两个相邻的变量,由于缓存是按缓存块来组织的,当一个线程对一个缓存块执行写操作时,必须使其他线程含有对应数据的缓存块无效。这样两个线程都会同时使对方的缓存块无效,导致性能下降。

在Java中,解决伪共享通常有这些方法:

另外,在 JDK 1.8 中,提供了 @sun.misc.Contended 注解,使用该注解就可以让变量独占缓存行,不再需要手动填充了。 注意,JVM 需要添加参数 -XX:-RestrictContended 才能开启此功能。


在多核情况下,每个核都有对应缓存,如果有一个 CPU 修改了内存中的某个值,那么怎么确保其他 CPU 能够感知到这个修改?

三、缓存一致性 & MESI协议

缓存写策略

当 CPU 修改了缓存中的数据后,这些修改什么时候能传播到主存?解决这个问题有两种策略:写回(Write Back)和写直达(Write Through)。


到这里就是乱码的啦,还没写完,下次继续

链接:

这里怎么和Redis 的 AOF 以及

缓存一致性问题

通过该协议,确保多核缓存之间的一致性

对于主流的CPU来说,缓存的写操作基本上是两种策略(参看《缓存更新的套路》),

  • 一种是Write Back,写操作只要在cache上,然后再flush到内存上。
  • 一种是Write Through,写操作同时写到cache和内存上。

为了提高写的性能,一般来说,主流的CPU(如:Intel Core i7/i9)采用的是Write Back的策略,因为直接写内存实在是太慢了。

好了,现在问题来了,如果有一个数据 x 在 CPU 第0核的缓存上被更新了,那么其它CPU核上对于这个数据 x 的值也要被更新,这就是缓存一致性的问题。(当然,对于我们上层的程序我们不用关心CPU多个核的缓存是怎么同步的,这对上层的代码来说都是透明的) 。

MESI协议

15 | MESI协议:多核CPU是如何同步高速缓存的?-极客时间

MESI协议 存在的性能问题,怎么处理?

四、Store buffer&内存屏障

Store buffer

store buffer 也会有一个问题,那就是它并不能保证变量写入缓存和主存的顺序

内存屏障

屏障的作用是前边的读写操作未完成的情况下,后面的读写操作不能发生


参考

1、编程高手必学的内存知识-极客时间

2、与程序员相关的CPU缓存知识 | 酷 壳 - CoolShell

3、记住这两幅重要的图!-码农翻身


http://www.ppmy.cn/news/813736.html

相关文章

我的世界服务器皮肤文件夹在哪里,我的世界青龙皮肤文件,启动侠皮肤文件夹在哪个文件夹...

你皮肤站&#xff0c;我的世界人物皮肤文件夹是哪个文件夹要先创建角色&#xff0c;填上名字&#xff0c;创建角色完毕。然后要选择皮肤&#xff0c;保存之后。进入mc看看有没有你的皮肤&#xff0c;如果没有&#xff0c;就代表你没有皮肤站里面的小插件&#xff0c;那就下载皮…

微信小程序原声自定义日期选择器

date.wxml <view><!-- table表格--><view class"table-container"><!-- 年份 月份选择 --><view class"table-date"><view><span bindtap"back" data-date"year" class"table-dateFont…

微信公众号测试环境开发

在公众平台沙箱环境中注册 https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?actionshowinfo&tsandbox/index 获取appID和appsecret 测试号信息 appID wxf4da******0e17 appsecret f57f1fa521******0e4bb3 接口配置信息 填写接收微信推送消息接口的URL与token&…

【SpringBoot+VUE后台管理系统】(六)Excel导入导出功能实现

文章目录 一、导入hutool 工具包以及poi相关依赖二、编写用户导出接口三、导入接口实现1、方式一2、方式二四、前端用户管理对接导入1、导出按钮添加点击事件2、在axios.js中将请求的BaseUrl也放到vue容器中3、定义导出的方法 获取BaseUrl进行拼接导出的接口地址3、导出的数据加…

android微信怎么建群,微信可以建群吗 图文教你微信怎么建群

微信可以建群吗 图文教你微信怎么建群 来源&#xff1a;www.18183.com作者&#xff1a;皮卡时间&#xff1a;2016-06-23 微信现在可以说是大家日常生活中必不可少的一款聊天工具了&#xff0c;其势头甚至可以逐渐与QQ媲美。那么&#xff0c;如果在微信聊天的过程中怎么建群呢&a…

微信支付退款--原生PHP实现代码 20230513

后端 $appidwx1234567890; //这是公众号的appid $mch_id1500000000; //商户号&#xff08;登录 pay.weixin.qq.com&#xff0c;在【产品中心】-【开发配置】里会看到&#xff09; $nonce_strabcdddddddddddd;//随机字符串&#xff0c;随便一串字母即可 $out_refund_nor.time()…

Android studio 微信界面设计

一、微信界面的功能 1、可展示出四个可切换界面&#xff1a;微信、联系人、朋友圈、设置&#xff1b; 2、上方栏标题居中&#xff0c;界面中间显示内容&#xff0c;内容随下方栏的选择而切换&#xff0c;下方栏可点击切换&#xff0c;点击过的界面的图标为绿色&#xff0c;没有…

mpvue实现微信小程序样式切换以及本地缓存

功能描述&#xff1a; 在页面A的添加应用中点击”添加“&#xff0c;跳转到展示所有应用的页面B&#xff0c;通过点击开关&#xff0c;在页面A中展示所开启的应用 效果展示&#xff1a; 代码&#xff1a; 页面B代码&#xff1a; <div class"itembox" v-for&quo…