ARMv8 Load / store 指令学习重要笔记

注:本文转载来源:http://blog.csdn.net/forever_2015/article/details/52653439

ARMv8 Load / store 指令学习重要笔记

1Load-Store Non-temporal Pair

STNP Xt1, Xt2, [base,#imm]

Store Non-temporal Pair (extended): stores two doublewords from Xt1 and Xt2 to memory addressed by

base+imm, with a non-temporal hint.  

表示这个指令带有隐含意义(hint),直接存取外存,不经过cache,其他指令都会经过cache

该指令用于你确定知道该地址只加载一次,不需要触发缓存,避免资料被刷新,优化性能。

三级存储,存储速度由高到低:寄存器 -->高速缓存(一级/二级)--> 内存


2Load-Store Unprivileged

LDTRSB Xt, [base,#simm9]

Load Unprivileged Signed Byte (extended): loads a byte from memory addressed by base+simm9, then sign-extends it into Xt, using EL0 privileges when at EL1

EL0/EL1的内存有不同的权限控制,这条指令以EL0的权限存取,用于模拟EL0的行为。

应该用于EL1EL0之间的交互。

3Load-Store Single Register (unscaled offset)

LDUR Xt, [base,#simm9]  //比如这个就是从内存地址base+#simm9读取双字数据到Xt,而 #simm9 属于 -256 ~ +256直接的任何整数.

本质就是是否乘以一个常量,因为scaled的总是可以乘以一个常量来达到对齐,而unscaled就不需要,是多少就多少,更符合人类自然的理解。


4Load-Store Exclusive(独占)

STXP Ws, Xt, Xt2, [base{,#0}]

Store Exclusive Pair (extended): stores two doublewords from Xt and Xt2 to memory addressed by base, and sets Ws to the returned exclusive access status.

----把两个双字数据XtXt2写到内存地址(base)中,设置Ws为被返回的独占访问状态

在多核CPU下,对一个地址的访问可能引起冲突,这个指令解决了冲突,保证原子性(所谓原子操作就是不能被中断的操作),就是解决多个CPU访问同一内存地址导致冲突的一种机制。

比如2CPU同时写,其中一条的Ws就会返回失败值。

通常用于锁,比如spinlock

可以看下代码:arch/arm64/include/asm/spinlock.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
static  inline  void  arch_read_lock(arch_rwlock_t *rw)
{
     unsigned  int  tmp, tmp2;
 
     asm  volatile (
     "   sevl\n"
     "1: wfe\n"
     "2:  ldaxr    %w0, %2\n"
     "   add %w0, %w0, #1\n"
     "   tbnz    %w0, #31, 1b\n"
     "    stxr     %w1, %w0, %2\n"
     "   cbnz    %w1, 2b\n"
     "=&r"  (tmp),  "=&r"  (tmp2),  "+Q"  (rw->lock)
     :
     "cc" "memory" );
}
 
static  inline  void  arch_read_unlock(arch_rwlock_t *rw)
{
     unsigned  int  tmp, tmp2;
 
     asm  volatile (
     "1:  ldxr     %w0, %2\n"
     "   sub %w0, %w0, #1\n"
     "    stlxr    %w1, %w0, %2\n"
     "   cbnz    %w1, 1b\n"
     "=&r"  (tmp),  "=&r"  (tmp2),  "+Q"  (rw->lock)
     :
     "cc" "memory" );
}


5Load-Acquire / Store-Release

这是内存屏障

    1. Data Memory Barrier (DMB, non-blocking inst)
        1. DMB保证该指令前的所有内存访问结束,而该指令之后引起的内存访问只能在该指令执行结束后开始
        2. 其他非内存访问指令还是可以乱序执行
    2.  Load-Acquire ( 含有 Acquire语义的读操作 )
        1. 相当于单向向后的屏障 (半个DMB)

          只保证该指令之后引起的内存访问只能在该指令结束之后开始

    1.  Store-Release ( 含有Release语义的写操作 )
        1. 相当于单向向前的屏障 (半个DMB)

          只保证该指令前的所有内存访问结束后开始执行

    1. 使用Load-Acquire/ Store-Release指令可省去DMB ,有助于优化代码

 

    1. Data synchronization Barrier (DSB, block inst)
        1. DMB严格,DSB保证该该指令前的所有指令执行结束
    2. Instruction Synchronization Barrier (ISB, blocking inst)
        1. Flush pipeline

       ISB之后的指令刷掉重新从cache/memory取指

       之前的指令执行完毕

        1. 保证context切换相关的操作(取指相关)ISB之后生效

       修改ASID

       执行TLB/branch predictor maintenance操作

       等其他改变CP15寄存器的操作


--本质是为了解决乱序执行中有依赖关系的指令可以按正确的逻辑执行的一种机制,而DMB,DSB,ISB的强制性(权限)由低到高


DMB 只管内存访问指令屏障.

DSB 管所有指令屏障.

ISB 指令之后的pipeline全部被flush掉,重新从memory中取指.


以DMB为例:

ADD X1,X2,X3       -----(A)

LDR X4,addr         -----(B)

STR X6,addr2

DMB <option>         -----(DMB)

LDR X5,addr3        -----(C)

STR X7,addr4

SUB X8,X9,#2

...


以上(C)必须要等(B)执行完成后才可以执行,因为有(DMB)的屏障作用,而(A)不属于内存访问指令,也和其他指令没有依赖关系,可以越过(DMB)屏障乱序执行;


而结合到load-acquire/store-release,可以理解为半个DMB指令,load-acquire只管读 memory,而store-release只管写memroy,组合使用可以增加代码灵活性和执行效率.


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值