通常我們代碼中的a = a + 1
這樣的一行語句,翻譯成匯編后蘊含著 3 條指令:
ldr x0, &a
add x0,x0,#1
str x0,&a
即
(1) 從內存中讀取 a 變量到 X0 寄存器
(2)X0 寄存器加 1
(3) 將 X0 寫入到內存 a 中
既然是 3 條指令,那么就有可能并發,也就意味著返回的結果可能不說預期的。
然后在 linux kernel 的操作系統中,提供訪問原子變量的函數,用來解決上述問題。其中部分原子操作的 API 如下:
atomic_read
atomic_add_return(i,v)
atomic_add(i,v)
atomic_inc(v)
atomic_add_unless(v,a,u)
atomic_inc_not_zero(v)
atomic_sub_return(i,v)
atomic_sub_and_test(i,v)
atomic_sub(i,v)
atomic_dec(v)
atomic_cmpxchg(v,old,new)
那么操作系統 (僅僅是軟件而已) 是如何保證原子操作的呢?(還是得靠硬件),硬件原理是什么呢?
以上的那些 API 函數,在底層調用的其實都是如下__lse_atomic_add_return##name
宏的封裝,這段代碼中最核心的也就是ldadd
指令了,這是 armv8.1 增加的 LSE(Large System Extension)feature。
(linux/arch/arm64/include/asm/atomic_lse.h)
static inline int __lse_atomic_add_return##name(int i, atomic_t *v)
{
u32 tmp;
asm volatile(
__LSE_PREAMBLE
" ldadd" #mb " %w[i], %w[tmp], %[v]n"
" add %w[i], %w[i], %w[tmp]"
: [i] "+r" (i), [v] "+Q" (v- >counter), [tmp] "=&r" (tmp)
: "r" (v)
: cl);
return i;
}
那么系統如果沒有 LSE 擴展呢,即 armv8.0,其實現的原型如下所示,這段代碼中最核心的也就是ldxr
、stxr
指令了
(linux/arch/arm64/include/asm/atomic_ll_sc.h)
static inline void __ll_sc_atomic_##op(int i, atomic_t *v)
{
unsigned long tmp;
int result;
asm volatile("http:// atomic_" #op "n"
__LL_SC_FALLBACK(
" prfm pstl1strm, %2n"
"1: ldxr %w0, %2n"
" " #asm_op " %w0, %w0, %w3n"
" stxr %w1, %w0, %2n"
" cbnz %w1, 1bn")
: "=&r" (result), "=&r" (tmp), "+Q" (v- >counter)
: __stringify(constraint) "r" (i));
}
那么在 armv8.0 之前呢,如 armv7 是怎樣實現的?如下所示, 這段代碼中最核心的也就是ldrex
、strex
指令了
(linux/arch/arm/include/asm/atomic.h)
static inline void atomic_##op(int i, atomic_t *v)
{
unsigned long tmp;
int result;
prefetchw(&v- >counter);
__asm__ __volatile__("@ atomic_" #op "n"
"1: ldrex %0, [%3]n"
" " #asm_op " %0, %0, %4n"
" strex %1, %0, [%3]n"
" teq %1, #0n"
" bne 1b"
: "=&r" (result), "=&r" (tmp), "+Qo" (v- >counter)
: "r" (&v- >counter), "Ir" (i)
: "cc");
}
總結:
在很早期,使用 arm 的 exclusive 機制來實現的原子操作,exclusive 相關的指令也就是ldrex
、strex
了,但在 armv8 后,exclusive 機制的指令發生了變化變成了ldxr
、stxr
。
但是又由于在一個大系統中,處理器是非常多的,競爭也激烈,使用獨占的存儲和加載指令可能要多次嘗試才能成功,性能也就變得很差,在 armv8.1 為了解決該問題,增加了ldadd
等相關的原子操作指令。
-
處理器
+關注
關注
68文章
18929瀏覽量
227280 -
寄存器
+關注
關注
31文章
5254瀏覽量
119214 -
Linux系統
+關注
關注
4文章
587瀏覽量
27183 -
LSE
+關注
關注
0文章
10瀏覽量
10213 -
ARMv8
+關注
關注
1文章
35瀏覽量
14105
發布評論請先 登錄
相關推薦
評論