【Cache篇】Cache伪共享

🌟🌟🌟博主主页:MuggleZero 🌟🌟🌟

 《ARMv8架构初学者笔记》专栏地址:《ARMv8架构初学者笔记》

前文:

【Cache篇】初见Cache

【Cache篇】Cache的映射方式

【Cache篇】包容性和排他性的Cache

【Cache篇】Cache的分类

【Cache篇】MESI协议

cache是以cache line为单位去内存中取数据并且缓存数据的,一般来说cache line的大小为64字节。当访问long类型数组中某个成员时,CPU会将临近的数组成员都加载到痛一个cache line中,这样可以加速访问。问题是,如果此时有另一个处理器也想访问临近的数组成员,这就回导致这个cache line被频繁的导入导出,造成很大的性能问题。所以这就是cache伪共享。

cache伪共享分析

假设,CPU0上的线程0想访问和更新x,CPU1上的线程1想访问和更新y,x和y都被加载到了一个cache line中。

现在我们根据MESI协议来分析cache line的使用情况:

  1. CPU0第一次访问x,由于此时cache还没有数据x,所以此时cache line0为I。在CPU0将data放进cache line0后,此时cache line0的状态为E。

  2. CPU1第一次访问y时,由于此时y已经缓存在了CPU0的cache line0中,并且此cache line0状态为E。CPU1向总线发起读请求,CPU0收到请求后,将这个cache line0的数据发到总线上。CPU1获取到数据后,经本地cache line1和远程的cache line0设置为S。此时所有的cache line都是S状态。

  3. CPU0想更新x时,CPU0和CPU1的cache line都是S。CPU0发送BusUpgr到总线上,然后修改本地的cache line0数据,将其改成M状态。在CPU1收到BusUpgr信号后,必须将本地的cache line1副本设置为I。(更新数据必须关闭其他的副本)(这里只更新了x,y没有更新

  4. CPU1想更新y时,此时CPU1的cache line1为I。CPU0上的cache line0缓存了旧数据y,且cache line0状态为M。CPU1发起本地写请求,根据MESI协议,CPU1发送BusRdX到总线上(广播信号,人人都能听到)。CPU0在收到信号后,发出应答信号。由于此时CPU0上的cache line0缓存了旧数据y,且cache line0状态为M。CPU0会先将数据放到内存,将cache line0设置为I,然后CPU1才可以修改cache line1的数据y,cache line1改成M。

  5. CPU0想修改x的过程和4类似。

两个CPU像4和5一样不断争夺cache line控制权,不断使对方的cache line失效,写数据回内存的行为导致性能下降。这种行为就叫做cache伪共享

cache伪共享的解决

解决cache伪共享的思想是对于多线程操作的数据,使得数据处在不同的cache line。

例如采用cache line填充/cache line对齐,让数据结构按照cache line行的大小(例如64字节对齐)对齐。

欢迎关注我的个人微信公众号,一起交流学习嵌入式开发知识!

关注「求密勒实验室」

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

漫游嵌入式

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值