什么时候需要cpu_relax()锁

一个最典型的要使用cpu_relax()锁的场景是忙等待(也就是死循环等一个事情的发生),在内核里面有大量的代码,

比如等寄存器状态:

8bbd1441f566c3126459efcfc9857306.png

比如做延迟:

8dbb561c7475fa3380159ab36aaf6e3f.png  

简单来说,你如果在内核里面写了忙等待的代码,都没有在循环里面加个cpu_relax()的话,这基本上是一种比较幼稚的表现。

根据内核文档volatile-considered-harmful,cpu_relax()的描述:

d756bc60f7119fe2d3f180269e9ab255.png

由此可见cpu_relax()至少具备三大功能:

1,  帮着省电;

2,  如果是超线程CPU的机器,可以让渡CPU给其他的线程;因为我这个CPU目前没什么正经事情干,等的时间不如放慢节奏,让别人多干点;

3,  它是一个编译屏障,让volatile变地在内核基本没什么必要。

当然,cpu_relax()的具体实现与体系架构相关,不同的体系架构实现不一样,可能只完成了上面3个功能中的1个,2个而不是全部。

我们看看它在ARM64的实现:

0c86c810f9a7d3a09ae0c9340b470242.png

其中"memory"的部分是服务于屏障功能,而前面的yield符合SMT系统让渡的语义。在典型的超线程处理器中,每个超线程不是一个独立的core,所以两个或者多个超线程之间仍然在竞争一些资源,如果其中一个人调用了yield,那么它会在争抢中放慢节奏,而旁边的那个兄弟会抢地更多

PowerPC的实现则是调节hardware multi-threading的优先级:

b87818b1e804b4420ab5bdd7b77a7c84.png

 当然,硬件如果不具备这种超线程能力的话,cpu_relax()可以简单地是一个编译屏障,

#define cpu_relax()     barrier()

比如 arch/alpha/include/asm/processor.h 中:

0471861b2a140835291c0f837f4de40a.png

REP NOP这种pause操作既可以省点,有可以避免忙等的CPU疯狂去抢总线访问内存。如果纯粹地不加pause暗示的忙等,疯狂执行指令,应该是很耗电的,忙等中拼命访问内存,总线冲突也大。

总之,不管具体的体系架构怎么实现,忙等里面都适合加cpu_relax(),毕竟内核多数的代码要求是跨平台的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值