Cortex-A510——内存屏障/壁垒(DMB/DSB/ISB)

Cortex-A510——内存屏障/壁垒(DMB/DSB/ISB)

小狼@http://blog.csdn.net/xiaolangyangyang


1、DMB/DSB/ISB

  • __DMB指令:

        Data Memory Barrier(数据存储器隔离),DMB指令保证所有前面的存储器访问操作执行完毕后,才提交后面的存储器访问操作;

  • __DSB指令:

        Data Synchronization Barrier(数据同步隔离),比DMB严格,前面所有存储器访问操作执行完毕后,才执行后面的指令;

  • __ISB指令:

        Instruction Synchronization Barrier(指令同步隔离),清洗流水线,保证所有前面的指令执行完毕后,才执行它后面的指令。

2、三种指令的典型案例

1、DMB
        DMB指令保证了两个内存访问能按正确的顺序执行。实际上DMB在Cortex-M的处理器中用得并不多,因为Cortex-M处理器不会重新排序内存事务(Memory transaction)。但如果想要软件能在其他ARM处理器上重用(如Cortex-M移植到Cortex-A),尤其是在多主系统中,DMB是必要的。下面举几个例子:
        (1)DMA
        使用DMA控制器时,在CPU内存访问和DMA操作之间插入DMB屏障,以确保CPU当前的内存读写操作在DMA开始之前完成。
        (2)多核系统中的信号量
        在多核系统中,使用信号量进行核间同步。需要使用DMB来强制指定内存执行顺序,以避免潜在的竞态条件或数据不一致性。
        当一个核要访问共享资源之前,它会先检查信号量的状态。如果信号量已经被另一个核获取,当前核就必须等待,直到信号量状态变为可用。这个等待过程需要保证在一个核释放信号量之后,其他核能够立即看到信号量状态的变化,而不是因为处理器优化或缓存导致的无效读取而产生错误。
        在这里,DMB的作用就是强制执行内存顺序。通过在核获取信号量之前插入DMB屏障,确保在DMB之前的所有内存操作都完成。这样,在一个核释放信号量之后,其他核获取信号量的操作能够看到最新的信号量状态,从而实现正确的同步。
        (3)多核系统中的邮箱
        类似地,在核之间通过邮箱机制通信时,需要使用DMB来对邮箱的内存访问正确顺序,避免通信问题。
2、DSB
        在Cortex-M处理器中,DSB可以用来:
        (1) 确保对SCS(System Control Space)的修改在下一条指令执行之前生效
        在ARM Cortex-M处理器中,SCS是一个特殊的内存区域,包含了一些系统控制寄存器和配置信息,用于管理处理器和系统的各种功能和特性。访问SCS的寄存器可以影响处理器的行为,例如启用或禁用特定的中断、配置时钟、设置系统控制位等。为了确保对SCS的修改在下一条指令执行之前生效,需要使用DSB指令进行数据同步。
        (2)确保在执行特权级指令之前,内存中的数据已经更新
        在ARM Cortex-M处理器中,一些特殊的指令如SVC(Supervisor Call,特权级调用)、WFI(Wait For Interrupt,等待中断)、WFE(Wait For Event,等待事件)等操作,涉及到特权级的转换或者等待系统事件发生,需要使用DSB指令。
3、ISB
        ISB指令用于清空流水线,确保在ISB指令之前的所有上下文修改操作的效果被后续操作正确识别。有一个很典型的例子:
        (1)CONTROL寄存器的修改
        在修改CONTROL寄存器后,应该使用ISB指令。比如我们修改CONTROL寄存器中的相关字段以进入特权模式,然后下一行代码就是一些特权操作,在这之前就需要使用ISB指令来让处理器正确识别新的特权级。

3、自旋锁、内存屏障、总线之间的关系

        和一致性相关的是访存次序。假设我们有两个核C0和C1。当C0和C1分别访问同一地址A0,无论何时,都要保证看到的数据一致,这是一致性。然后在C0里面,它需要保证先后访问地址A0和A1,这称作访问次序,不需要锁,只需要壁垒指令。如果C0和C1上同时运行两个线程,当C0和C1分别访问同一地址A0,并且需要保证C0和C1按照先后次序访问A0,这就需要锁。所以,单单壁垒指令只能保证单核单线程的次序,多核多线程的次序需要锁。而一致性保证了在做锁操作时,同一变量在缓存或者内存的不同拷贝,都是一致的。
        ARM的壁垒指令分为强壁垒DSB弱壁垒DMB强壁垒要求上一条读写指令完成后才能开始下一个请求,弱壁垒则只要求上一条读写指令发出请求后就可以继续下一条读写指令的请求,且只能保证,它之后的读写指令完成时,它之前的读写指令肯定已经完成了。显然,后一种情况性能更高,OT>1。但测试表明,多个处理器组的情况下,壁垒指令如果传输到总线,只能令整体系统性能降低,因此在新的ARM总线中是不支持壁垒的,必须在芯片设计阶段,通过配置选项告诉处理器自己处理壁垒指令,不要送到总线。但这并不影响程序中的壁垒指令,处理器会在总线之前把它过滤掉

        如果只需要保证读写次序,用弱壁垒;如果需要某个读写指令完成才能做别的事情,用强壁垒。以上都是针对普通内存类型。当我们把类型设成设备时,自动保证强壁垒。

3.1 CCI
        在CCI总线中,首先,壁垒和读写一样,也是使用读写通道的,只不过它地址总是0,且没有数据。标志符也是有的,此外还有额外的2根线BAR0/1,表明本次传输是不是壁垒,是哪种壁垒。他是怎么传输的呢?

3.1.1 弱壁垒
        先看弱壁垒,如下图:

        Master0写了一个数据data,然后又发了弱壁垒请求。CCI和主设备接口的地方,一旦收到壁垒请求,立刻做两件事,第一,给Master0发送壁垒响应;第二,把壁垒请求发到和从设备Slave0/1的接口。Slave1接口很快给了壁垒响应,因为它那里没有任何未完成传输。而Slave0接口不能给壁垒响应,因为data还没发到从设备,在这条路径上的壁垒请求必须等待,并且不能和data的写请求交换次序。这并不能阻挠Master0发出第二个数据,因为它已经收到它的所有下级(Master0接口)的壁垒回应,所以它又写出了flag。
        此时,flag在Master0接口中等待它的所有下一级接口的壁垒响应。而data达到了Slave0后,壁垒响应走到了Master0接口,flag继续往下走。此时,我们不必担心data没有到slave0,因为那之前,来自Slave0接口的壁垒响应不会被送到Master0接口。这样,就做到了弱壁垒的次序保证,并且在壁垒指令完成前,flag的请求就可以被送出来。

3.1.2 强壁垒
        对于强壁垒指令来说,仅仅有一个区别,就是Master0接口在收到所有下一级接口的壁垒响应前,它不会发送自身的壁垒响应给Master0。这就造成flag发不出来,直到壁垒指令完成。如下图:

        这样,就保证了强壁垒完成后,下一条读写指令才能发出请求。此时,强壁垒前的读写指令肯定是完成了的。

3.2 锁和原子操作
        壁垒只是针对单核。在多核多线程时,哪怕使用了壁垒指令,也没法保证读写的原子性。解决办法有两个,一个是软件锁,一个是原子操作。原子操作有两种,一种是总线收到请求时,直接封掉整个总线,同时只有一个核能访问。这样效率很低。还有个方法是把锁的请求发送到对端设备,比如内存控制器,让他禁止别的核的访问,而总线依然可以运行,这样效率就高不少。

3.2.1 自旋锁
        软件锁中有个自旋锁,能用一个ARM硬件机制exclusive access来实现。当使用特殊指令对一个地址写入值,相应缓存行上会做一个特殊标记,表示还没有别的核去写这行缓存。然后下条指令读这个行,如果标记没变,说明写和读之间没有人打扰,那么就拿到锁了。如果变了,那么回到写的过程重新获取锁。由于缓存一致性,这个锁变量可以被多个核与线程使用。当然,过程中还是需要壁垒指令来保证次序

NOC CCN NIC CCI总线


ARM基础(6):内存屏障指令之DMB、DSB和ISB详解
ARM进阶:内存屏障(DMB/DSB/ISB)的20个使用例子详解

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值