Linux内核同步机制之:Per-CPU变量

一、源由:为何引入Per-CPU变量?

1、lock bus带来的性能问题

在ARM平台上,ARMv6之前,SWP和SWPB指令被用来支持对shared memory的访问:

Rn中保存了SWP指令要操作的内存地址,通过该指令可以将Rn指定的内存数据加载到Rt寄存器,同时将Rt2寄存器中的数值保存到Rn指定的内存中去。

我们在原子操作那篇文档中描述的read-modify-write的问题本质上是一个保持对内存read和write访问的原子性的问题。也就是说对内存的读和写的访问不能被打断。对该问题的解决可以通过硬件、软件或者软硬件结合的方法来进行。早期的ARM CPU给出的方案就是依赖硬件:SWP这个汇编指令执行了一次读内存操作、一次写内存操作,但是从程序员的角度看,SWP这条指令就是原子的,读写之间不会被任何的异步事件打断。具体底层的硬件是如何做的呢?这时候,硬件会提供一个lock signal,在进行memory操作的时候设定lock信号,告诉总线这是一个不可被中断的内存访问,直到完成了SWP需要进行的两次内存访问之后再clear lock信号。

lock memory bus对多核系统的性能造成严重的影响(系统中其他的processor对那条被lock的memory bus的访问就被hold住了),如何解决这个问题?最好的锁机制就是不使用锁,因此解决这个问题可以使用釜底抽薪的方法,那就是不在系统中的多个processor之间共享数据,给每一个CPU分配一个不就OK了吗。

当然,随着技术的发展,在ARMv6之后的ARM CPU已经不推荐使用SWP这样的指令,而是提供了LDREX和STREX这样的指令。这种方法是使用软硬件结合的方法来解决原子操作问题,看起来代码比较复杂,但是系统的性能可以得到提升。其实,从硬件角度看,LDREX和STREX这样的指令也是采用了lock-free的做法。OK,由于不再lock bus,看起来Per-CPU变量存在的基础被打破了。不过考虑cache的操作,实际上它还是有意义的。

2、cache的影响

在The Memory Hierarchy文档中,我们已经了解了关于memory一些基础的知识,一些基础的内容,这里就不再重复了。我们假设一个多核系统中的cache如下:

每个CPU都有自己的L1 cache(包括data cache和instruction cache),所有的CPU共用一个L2 cache。L1、L2以及main memory的访问速度之间的差异都是非常大,最高的性能的情况下当然是L

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值