linux 内核同步互斥技术之cache 伪共享和隐含内存屏障

隐含内存屏障

内核的有些函数隐含内存屏障。
(1)获取和释放函数。
(2)中断禁止函数。

1.获取和释放函数
获取( acquire)函数包括如下。
(1)获取锁的函数。锁包括自旋锁、读写自旋锁、互斥锁、信号量和读写信号量。
(2) smp_load_acquire(p):加载获取。
(3) smp_cond_load_acquire(ptr, cond_expr):带条件的加载获取。

获取操作隐含如下。
(1)获取操作后面的内存访问操作只能在获取操作完成之后被观察到。
(2)获取操作前面的内存访问操作可能在获取操作完成之后被观察到。

释放(release)函数包括如下。
(1)释放锁的函数。
(2) smp_store_release(p, v):存储释放。

释放操作隐含如下。
(1)释放操作前面的内存访问操作必须在释放操作完成之前被观察到。
(2)释放操作后面的内存访问操作可能在释放操作完成之前被观察到。

获取操作和释放操作都是单向屏障。

有返回值的atomic操作
主要指以下方法:
        xchg();
        cmpxchg();
        atomic_cmpxchg();
        atomic_inc_return();
        atomic_dec_return();
        atomic_add_return();
        atomic_sub_return();
        atomic_inc_and_test();
        atomic_dec_and_test();
        atomic_sub_and_test();
        atomic_add_negative();
        atomic_add_unless();    /* when succeeds (returns 1) */
        test_and_set_bit();
        test_and_clear_bit();
        test_and_change_bit();
而这些方法是不隐含内存屏障的:
        atomic_set();
        set_bit();
        clear_bit();
        change_bit();
        atomic_add();
        atomic_sub();
        atomic_inc();
        atomic_dec();

2.中断禁止函数
禁止中断和开启中断的函数只充当编译器优化屏障。

cache 伪共享

我们熟悉了MESI状态的转换的之后,我们来看cache伪共享就简单多了。什么是cache伪共享呢?其实,我们知道一个cache line的大小是32字节或者64字节,如果两个频繁访问的数据A和B,他们共处在一个cache line里面,然后不同的CPU都在频繁的访问A或者B的数据,那么就会带来性能上的问题,可能这个cache line的状态要频繁的变来变去,造成一种无畏的颠簸,我们知道MESI本质上是要消耗系统内部总线的带宽的,你一个cache line的状态老是频繁的变来变去,总线带宽都被你消耗了不少,当然会引起性能的问题,所以,这个叫做cache伪共享(英文叫做false sharing)。
伪共享的避免:
第一个案例是cache的伪共享的避免。避免的方法主要有两个。
第一个是:一些常用的数据结构在定义时就约定数据结构以一级缓存对齐。例如使用如下的宏来让数据结构首地址以L1 cache对齐。下面这个宏是利用了GCC的特性,_attribute的属性,来让数据结构的起始地址以某个数字对齐,这里是以L1 cache对齐。
  
第二个是:数据结构中频繁访问的成员可以单独占用一个高速缓存行,或者相关的成员在高速缓存行中彼此错开,以提高访问效率。
例如struct zone数据结构使用ZONE_PADDING技术(填充字节的方式)来让频繁访问的成员在不同的cache line中。
  
所以,cache伪共享,在有些情况下是性能杀手,而且你又比较难去发现它,所以需要我们编程的时候,特别注意。你写的数据结构里,有没有可能出现 不同的CPU核心频繁访问某些成员,导致cache伪共享的?这个需要写程序的时候就要思考清楚。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一叶知秋yyds

分享是一种美德,感谢金主打赏

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

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

打赏作者

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

抵扣说明:

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

余额充值