免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: blake326
打印 上一主题 下一主题

[CPU及多核] smp cache line并发访问 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2014-06-29 22:24 |只看该作者
本帖最后由 blake326 于 2014-06-29 22:25 编辑

好吧没人回,我自己理解下,关键的一点:
“  状态为S时,数据将直接写入到Cache中,并将状态改为M,同时其他CPU保存该数据副本的Cache行状态将从S或者O迁移到I(Probe Write Hit)。”这个是否原子?
这个操作看起来有很多小步组成的,写数据到cache,修改m,同时发送inval request到其他cpu,可能还要处理其他cpu回来的inval replay。所以,当然不是原子的了,要不然肯 定很影响性能的。
但是,更关键的一点,mesi会保证整个一套动作是安全的,之前的例子,cpu0,cpu1同时写s的cache line,那么对于这同一个cache line,mesi应该会有一个同步机制(类似 mutex)之类的保证同时只有一个cpu操作了addr响应的cache line.比如,cpu0,cpu1同时开始写,首先,mesi会仲裁选择一个cpu进行对cache line进行操作,另外一个cpu只能等 待,待的就是之前说的一些列操作:状态为S时,数据将直接写入到Cache中,并将状态改为M,同时其他CPU保存该数据副本的Cache行状态将从S或者O迁移到I)。因此,我这个帖子 的结果就是,最终cache line的值是0, 1, 2, 3, 4, 5, 6, 7. arm-linux-gcc同志是正确的。

重新整理一下cache一致性的状态切换:
假设有cpu0, cpu1。一个虚拟地址addr。
则cpu0, cpu1都有一个addr对应的cache line, 状态有四种:有效E, 修改M,共享S, 无效I。I实际上就是说该addr在cache中没有缓存的意思。根据这四种状态,组合分析一下 。

cpu0,cpu1的cache状态一样:
都是I状态:
cpu0读的话,首先会像mesi申请cache line使用权,然后开始分配一个cache line并且从ddr把addr的值读取过来,状态变成E。
cpu0写的话,首先会像mesi申请cache line使用权,然后开始分配一个cache line并且从写addr,状态变成E。
都是S状态:
cpu0读的话,首先会像mesi申请cache line使用权,如果其他cpu已经获取了cache line的使用权的话,则这里要等待。获得cache line使用权之后,直接把cache line的值读出来 就好了。
cpu0写的话,首先会像mesi申请cache line使用权,cpu0写addr,修改本地cache,状态变成M,且发送一个inv消息给cpu1通知cpu1失效响应的cache line,当然cpu1应该会发送一 个inval replay回来。
都是E,M的状态是不存在的。因为,E/M状态的核心一点就是表示cache line只在本地cpu中存在,不存在竞争关系。

cpu0,cpu1的cache状态不一样:
cpu0 I,  cpu1 E:
cpu0 读addr,首先会像mesi申请cache line使用权,发现cpu1有对应的E cache,新建一个本地的cache line将cpu1的cache line拷贝过来,并且设置大家的状态为S。
cpu0 写addr,首先会像mesi申请cache line使用权,发现cpu1有对应的E cache,发送一个inv消息告诉cpu1,并且等待其inval replay返回,然后本地新建一个cache line将ddr 读进来,之后修改本地cache line,并且设置状态M。
cpu1 读addr,因为E状态,无需向mes申请cache line使用权,直接读cache。
cpu1 写addr,因为E状态,无需向mes申请cache line使用权,直接写cache,设置状态为M。

cpu0 I, cpu1 M:
cpu0 读addr,首先会像mesi申请cache line使用权,发现cpu1有对应的M cache,发送一个flush消息告诉cpu1并且等待cpu1刷新cache到ddr,然后新建一个本地cache line将ddr 从内存读进来,并且设置状态为E。
cpu0 写addr,首先会像mesi申请cache line使用权,发现cpu1有对应的M cache,发送一个flush消息告诉cpu1并且等待cpu1刷新cache到ddr,然后新建一个本地cache line将ddr 从内存读进来并且写,并且设置状态为M。
cpu1 读addr,因为M状态,无需向mes申请cache line使用权,直接读。
cpu1 写addr,因为M状态,无需向mes申请cache line使用权,直接写。



cpu乱序模型:
http://bbs.chinaunix.net/thread-3593865-1-1.html


cpu乱序,cache一致性,和内存屏障。
内存屏障mb() 是和cpu乱序,chache一致性相关的。下面的老例子:
cpu0
a = 1;
wmb();
b = 2;

cpu1
读 b;
rmb();
读 a;

cpu乱序模型会让a=1,a=2执行顺序颠倒。 读b,读a顺序颠倒。
wmb() 会使 a=1先执行,然后再执行 b=1, 说的再细一点同cache一致性就有关系了,因为a=1,之前说了是一个很多小步骤组成的过程,获取cache使用权,写cache,发送inval a ,修改m状态。wmb实际上就是保证,在wmb之前所有的inval request已经发了出去。就是说保证先发inval a, 然后再发inval b.

rmb() 会先执行读b,然后再执行读a,仔细一点,实际上就是说在rmb之前所有的inval request完成了。那么,我们刚才已经知道了cpu1先收到的inval a然后是inval b,假设在 rmb()时,inval b已经执行了,那么这个时候会处理掉所有的inval request,确保inval a也应执行了。就是说cpu1假设读到了b=2,那么rmb()之后,a肯定是1.



cache alias:
http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=1972593

cache一般有几种类型:
pipt
vivt
vipt noalias
vipt alias

实际上armv7 的dcache是vipt noalias的。icache是vipt alias的。
为什么会有cache alias问题呢,为什么amv7 dcache又没有呢。

一个cache由 cache line size * num set * way 组成。
一般是 32 * 256 * 4 = 32KB.
如果line size * num set = 8KB大于page size的话那么就有可能有alias问题。
假设0xf000 0000和0xf000 1000两段地址都是映射同一个page的话,那么访问0xf000 0000和0xf000 1000时,他们在cache中的num是不同的,就是有各自的cache line,但是映射的物理地址是一样的。如果硬件不能自动处理的话,软件一定要处理好。
现在假设dcache是vipt alias的话,文件系统写一个page cache时,会调用flush_dcache_page()来解决这个alias问题。
最终会调用到flush_pfn_alias(),好久不看相关的东西,看不懂这个鸟玩意了,请高手帮忙分析下。


论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
12 [报告]
发表于 2014-06-30 13:47 |只看该作者
回复 7# arm-linux-gcc

请教下:MESI是否有队列做串行化?假设core 0和 core 1都写了自己的 L1,然后同时发起 inval,谁成功?失败者是否会得到通知并且重新 RFO再次写入?

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
13 [报告]
发表于 2014-06-30 13:49 |只看该作者
回复 11# blake326


mesi会保证整个一套动作是安全的


MESI作为 cache coherency protocol 硬件上应该需要保证其串行,但是这个细节的确没 google到,请赐教!

论坛徽章:
0
14 [报告]
发表于 2014-06-30 13:55 |只看该作者
回复 13# asuka2001


    这个帖子本来我就是这个疑问的。
    所以想了想,为什么cache有这么几种状态,要把i,s, 和 m,e区分开来。m和e cache可以直接操作,而i,s 的cache所以会有一个保护同步机制。
    所以,都是猜的。

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
15 [报告]
发表于 2014-06-30 14:01 |只看该作者
回复 14# blake326

可能要找找硬件实现了,以前没仔细考虑过这个问题,你的这个问题很有价值:)

大家可以更加深入的讨论下 MESI的状态转化和底层硬件上的实现问题,比如 M -> S我记得是由硬件 snoop完成的。。。但是 inval怎么实现的,如何保证顺序性,这些就不清楚了!

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
16 [报告]
发表于 2014-06-30 14:27 |只看该作者
回复 12# asuka2001


    应该是有串行化处理的,SCU应该会仲裁的

其中一些细节和过程我也不清楚,得找时间看看这方面的资料先

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
17 [报告]
发表于 2014-07-01 08:12 |只看该作者
回复 16# arm-linux-gcc

我搜索了一下 arm的 architecture spec,没有比较详细准确的定义,估计得翻具体的芯片手册看有没有。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP