1、Load-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。
该指令用于你确定知道该地址只加载一次,不需要触发缓存,避免资料被刷新,优化性能。
三级存储,存储速度由高到低:寄存器 -->高速缓存(一级/二级)--> 内存
2、Load-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的行为。
应该用于EL1和EL0之间的交互。
3、Load-Store Single Register (unscaled offset)
LDUR Xt, [base,#simm9] //比如这个就是从内存地址base+#simm9读取双字数据到Xt,而 #simm9 属于 -256 ~ +256直接的任何整数.
4、Load-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.
----把两个双字数据Xt,Xt2写到内存地址(base)中,设置Ws为被返回的独占访问状态
在多核CPU下,对一个地址的访问可能引起冲突,这个指令解决了冲突,保证原子性(所谓原子操作就是不能被中断的操作),就是解决多个CPU访问同一内存地址导致冲突的一种机制。
比如2个CPU同时写,其中一条的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"
);
}
|
5、Load-Acquire / Store-Release
这是内存屏障:
▪ 只保证该指令之后引起的内存访问只能在该指令结束之后开始
▪ 只保证该指令前的所有内存访问结束后开始执行
• ISB之后的指令刷掉重新从cache/memory取指
• 之前的指令执行完毕
• 修改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
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,组合使用可以增加代码灵活性和执行效率.