免费注册 查看新帖 |

Chinaunix

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

[推荐] LKML上一篇关于barrier文档草案的讨论 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2006-03-14 11:21 |只看该作者
检查代码发现. glibc NPTL中的自旋所采用的memory barrier都是SMP形式的,所以在可以同时在UP和SMP中使用.

但uClibc中的pthread_mutex_lock() 中的锁的实现中的memory barrier 采用的是UP形式的, 不知道uClibc x86在SMP中怎么用.

论坛徽章:
0
22 [报告]
发表于 2006-04-30 10:49 |只看该作者
对于CPU和外设之间的共享内存,最好通过将相应的页表属性设置为no_cached和来避免一致性问题。另外,powerPc构架CPU可以设置页表的guarded属性,禁止CPU对访问该页表所代表内存的读写访问重新排序。X86不知道有没有。。。。。

论坛徽章:
0
23 [报告]
发表于 2007-07-23 16:47 |只看该作者
原帖由 xiaozhaoz 于 2006-3-10 14:40 发表
看他们的意思,DMA读写内存部分代码用memory barrier好像也很复杂。有谁对这块比较了解,介绍一下?


重看这个帖子,才看到这句,老大现在弄明白DMA读写的barrier了吗?  《现代体系结构上的Unix系统》P89页有很好的讲解

论坛徽章:
0
24 [报告]
发表于 2007-07-23 18:05 |只看该作者
也写一下自己的总结:

       
  1.         内核中定义的内存屏障原语有:
  2.                
  3.                 #define barrier() __asm__ __volatile__("": : :"memory")
  4.                 #define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
  5.                 #define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)

  6.         #ifdef CONFIG_SMP
  7.                 #define smp_mb()        mb()
  8.                 #define smp_rmb()        rmb()
  9.                 #define smp_wmb()        wmb()
  10.                 #define smp_read_barrier_depends()        read_barrier_depends()
  11.                 #define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
  12.         #else
  13.                 #define smp_mb()        barrier()
  14.                 #define smp_rmb()        barrier()
  15.                 #define smp_wmb()        barrier()
  16.                 #define smp_read_barrier_depends()        do { } while(0)
  17.                 #define set_mb(var, value) do { var = value; barrier(); } while (0)
  18.         #endif


  19.         1). smp_xxx()和xxx()的区别
  20.                
  21.                 为了给其它CPU也提供相关的barrier宏。 例如x86的rmb()是用了lfence指令,但其它CPU不能用这个指令。


  22.         2). 关于barrier()宏,jkl大师是这么说的:

  23.                 CPU越过内存屏障后,将刷新自己对存储器的缓冲状态。这条语句实际上不生成任何代码,但可使gcc在
  24.                 barrier()之后刷新寄存器对变量的分配。
  25.        
  26.             也就是说,barrier()宏只约束gcc编译器,不约束运行时的CPU行为。 举例:
  27.                
  28.                 1        int a = 5, b = 6;
  29.                 2        barrier();
  30.                 3        a = b;
  31.        
  32.             在line 3,GCC不会用存放b的寄存器给a赋值,而是invalidate b的Cache line,重新读内存中的b值,赋值给a。


  33.         3). mb() vs. rmb() vs. wmb()

  34.             rmb()不允许读操作穿过内存屏障;wmb()不允许写操作穿过屏障;而mb()二者都不允许。

  35.             看IA32上wmb()的定义:
  36.             #ifdef CONFIG_X86_OOSTORE
  37.                     #define wmb() alternative("lock;addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM);
  38.             #else
  39.                     #define wmb() __asm__ __volatile__ ("": : :"memory");
  40.             #endif

  41.             Intel和AMD都没有在IA32 CPU中实现乱续写(Out-Of-Order Store),所以wmb()定义为空操作,不约束CPU行为;但
  42.             有些IA32 CPU厂商实现了OOO Store,所以就有了使用sfence的那个wmb()实现。
  43.        

  44.         4). 内存屏障的体系结构语义
  45.                
  46.            4.1) 只有一个主体(CPU或DMA控制器)访问内存时,无论如何也不需要barrier;但如果有两个或更多主体访问内存,且
  47.                 其中有一个在观测另一个,就需要barrier了。

  48.            4.2)        IA32 CPU调用有lock前缀的指令,或者如xchg这样的指令,会导致其它的CPU也触发一定的动作来同步自己的Cache。
  49.                 CPU的#lock引脚链接到北桥芯片(North Bridge)的#lock引脚,当带lock前缀的执行执行时,北桥芯片会拉起#lock
  50.                 电平,从而锁住总线,直到该指令执行完毕再放开。  而总线加锁会自动invalidate所有CPU对 _该指令设计的内存_
  51.                 的Cache,因此barrier就能保证所有CPU的Cache一致性。

  52.            4.3) 接着解释。
  53.                 lock前缀(或cpuid、xchg等指令)使得本CPU的Cache写入了内存,该写入动作也会引起别的CPU invalidate其Cache。
  54.                 IA32在每个CPU内部实现了Snoopying(BUS-Watching)技术,监视着总线上是否发生了写内存操作(由某个CPU或DMA控
  55.                 制器发出的),只要发生了,就invalidate相关的Cache line。 因此,只要lock前缀导致本CPU写内存,就必将导致
  56.                 所有CPU去invalidate其相关的Cache line。

  57.                 两个地方可能除外:
  58.                         -> 如果采用write-through策略,则根本不存在缓存一致性问题(Linux对全部内存采用write-back策略);
  59.                         -> TLB也是Cache,但它的一致性(至少在IA32上)不能通过Snoopying技术解决,而是要发送
  60.                            INVALIDATE_TLB_VECTOR这个IPI给其它的CPU。
  61.        
  62.           4.4) 进一步解释,MESI协议
  63.                
  64.                M:        Modified,已修改
  65.                E:        Exclusive,排他
  66.                S:        Shared,共享
  67.                I:        Invalid,无效

  68.                IA32 的CPU实现了MESI协议来保证Cache coherence。 CPU的总线监测单元,始终监视着总线上所有的内存写操作,
  69.                以便随时调整自己的Cache状态。

  70.                     -> Modified。 本CPU写,则直接写到Cache,不产生总线事物;其它CPU写,则不涉及本CPU的Cache,其它CPU
  71.                                   读,则本CPU需要把Cache line中的数据提供给它,而不是让它去读内存。
  72.                     
  73.                     -> Exclusive。只有本CPU有该内存的Cache,而且和内存一致。 本CPU的写操作会导致转到Modified状态。

  74.                     -> Shared。   多个CPU都对该内存有Cache,而且内容一致。任何一个CPU写自己的这个Cache都必须通知其它
  75.                                   的CPU。

  76.                     -> Invalid。  一旦Cache line进入这个状态,CPU读数据就必须发出总线事物,从内存读。


  77.          5) 考虑到DMA
  78.                 
  79.                 5.1). Wirte through策略。 这种情形比较简单。

  80.                       -> 本CPU写内存,是write through的,因此无论什么时候DMA读内存,读到的都是正确数据。
  81.                       -> DMA写内存,如果DMA要写的内存被本CPU缓存了,那么必须Invalidate这个Cache line。下次CPU读它,就
  82.                          直接从内存读。
  83.                
  84.                 5.2). Write back策略。 这种情形相当复杂。
  85.                  
  86.                       -> DMA读内存。被本CPU总线监视单元发现,而且本地Cache中有Modified数据,本CPU就截获DMA的内存读操作,
  87.                          把自己Cache Line中的数据返回给它。

  88.                       -> DMA写内存。而且所写的位置在本CPU的Cache中,这又分两种情况:
  89.                                       a@ Cache Line状态未被CPU修改过(即cache和内存一致),那么invalidate该cache line。
  90.                                  b@ Cache Line状态已经被修改过,又分2种情况:
  91.                                        
  92.                                         <1> DMA写操作会替换CPU Cache line所对应的整行内存数据,那么DMA写,CPU则invalidate
  93.                                             自己的Cache Line。
  94.                                         <2> DMA写操作只替换Cache Line对应的内存数据的一部分,那么CPU必须捕获DMA写操作的新
  95.                                             数据(即DMA想把它写入内存的),用来更新Cache Line的相关部分。

复制代码

论坛徽章:
0
25 [报告]
发表于 2009-10-28 15:39 |只看该作者
原帖由 albcamus 于 2007-7-23 18:05 发表
也写一下自己的总结:

       
        内核中定义的内存屏障原语有:
               
                #define barrier() __asm__ __volatile__("": : :"memory")
                #define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE ...


wmb已经不是空函数了

论坛徽章:
0
26 [报告]
发表于 2009-10-29 11:18 |只看该作者
原帖由 Solaris12 于 2009-10-28 15:39 发表


wmb已经不是空函数了


你变新手了?

好像intel和amd还是没有实现OOO store, 其他x86 vendor有实现OOO store的,所以wmb早就不是“所有x86都空函数”了,记得05年的时候就不是了。

论坛徽章:
8
羊年新春福章
日期:2015-03-19 02:03:312015亚冠之北京国安
日期:2015-06-16 22:04:45程序设计版块每日发帖之星
日期:2015-06-23 22:20:00每日论坛发贴之星
日期:2015-06-23 22:20:002015亚冠之首尔
日期:2015-06-24 19:18:072015亚冠之广州恒大
日期:2015-08-06 10:29:442015亚冠之柏太阳神
日期:2015-11-02 11:21:0515-16赛季CBA联赛之辽宁
日期:2015-12-09 15:05:02
27 [报告]
发表于 2015-01-03 23:38 |只看该作者
不好意思挖坟了....求Robert Love 原话....
回复 4# xiaozhaoz


   

论坛徽章:
0
28 [报告]
发表于 2016-08-05 14:02 |只看该作者
标记一下,待学习
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP