成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

loongarch架構介紹—內存模型和相關指令(二)

開發 架構
本文介紹了內存一致性模型、loongarch架構中內存一致性模型相關信息、原子指令和柵障指令的含義和使用方法,并結合自旋鎖的案例進行了說明

??想了解更多關于開源的內容,請訪問:??

??51CTO 開源基礎軟件社區??

??https://ost.51cto.com??

前言

前面一篇文章中介紹了loongarch架構中的基礎部分,包括基礎的整數運算指令、浮點運算指令、訪存指令等,以及loongarch架構中的一些寄存器約定和匯編寫法。

這篇文章則主要介紹loongarch架構中內存一致性模型相關信息,以及原子指令和柵障指令的含義和使用方法。本文會先介紹內存一致性模型相關背景知識,然后介紹目前loongarch資料中內存一致性模型相關的信息,再介紹loongarch中的原子指令和柵障指令,最后結合spinlock的實現說明原子指令和柵障指令的使用方法。

一、內存一致性模型

內存一致性模型(memory consistency model),簡稱內存模型(memory model),是描述程序的與shared memory相關的訪存指令執行順序行為的模型。對于一段程序,內存模型能夠指出哪些訪存指令執行順序是cpu允許存在的,哪些執行順序是不可能發生的。

對于一般應用程序的開發人員來說,內存一致性模型是透明的,代碼看上去是順序執行的,在多線程中通過調用系統封裝的互斥鎖等就可實現同步。

但對于系統開發人員,內存一致性模型需要了解,這關系到如底層匯編中自旋鎖實現等應用場景。

1、SC、TSO和RMO

這里列舉出一些常見的內存一致性模型:

  • Sequential Consistency (SC):順序一致性模型,不打亂訪存指令順序
  • Total Store Order (TSO):一種強序模型。x86的內存一致性模型類似于TSO
  • Relaxed Memory Order (RMO):弱序模型。如arm中支持一種RMO

其中Load表示加載內存操作,Store表示寫入內存操作。

除了SC模型外,其他幾種都打亂了訪存指令的執行順序,這主要是硬件上性能因素的考慮。

下面對這些模型中定義的訪存指令順序進行介紹。

(1)SC中訪存指令順序

對于Load和Store操作,實際上總共有4種順序:

  • Load->Load
  • Load->Store
  • Store->Store
  • Store->Load

SC模型保證以上所有的順序,即訪存指令實際的執行順序與其在程序中的先后順序相同。

下表為兩個cpu核并行運行的例子:

Core C1

Core C2

說明

S1: x = NEW

L1: r1 = y

S2: y = NEW

L2: r2 = x

x, y初始為0

其中,S1和S2為Store操作,L1和L2為Load操作,x和y是cpu核C1和C2中共享的變量,r1和r2是cpu核C1和C2中的局部變量。

SC中所有可能的執行順序如下:

  1. S1->L1->S2->L2,結果(r1, r2) = (0, NEW)
  2. S2->L2->S1->L1,結果(r1, r2) = (NEW, 0)
  3. S1,S2->L1,L2,結果(r1, r2) = (NEW, NEW)。其中S1和S2之間的順序,以及L1和L2之間的順序不確定

結果與一般程序員視角中的模型相同。

(2)TSO中訪存指令順序

TSO中保證的訪存指令順序如下:

  • Load->Load
  • Load->Store
  • Store->Store

其中對于Store->Load可能會被打亂順序。

下面用與上文SC中相同的例子進行說明:

Core C1

Core C2

說明

S1: x = NEW

L1: r1 = y

S2: y = NEW

L2: r2 = x

x, y初始為0

TSO中所有可能的執行順序如下:

  1. S1->L1->S2->L2,結果(r1, r2) = (0, NEW)
  2. S2->L2->S1->L1,結果(r1, r2) = (NEW, 0)
  3. S1,S2->L1,L2,結果(r1, r2) = (NEW, NEW)
  4. L1,L2->S1,S2,結果(r1, r2) = (0, 0)

可以看到,TSO中可以出現Load比Store先執行的情況,從而導致結果r1和r2均為0。

(3)RMO中訪存指令順序

在RMO中允許更進一步的亂序執行,如只保證以下順序:

  • Load->Load,且地址相同
  • Load->Store,且地址相同
  • Store->Store,且地址相同

2、同步方法

由于如TSO、RMO等內存模型中訪存指令的執行順序不確定,因此硬件上提供了利用原子指令和柵障指令(稱為fence或barrier等)來進行同步。程序中將需要同步的地方手動將其用原子指令和柵障指令進行標記,就能將目標代碼同步。

下面用一個例子進行說明:

Core C1

Core C2

S1: data1 = NEW

S2: data2 = NEW

F1: FENCE

S3: flag = SET

L1: r1 = flag

B1: if (r1 != SET) goto L1

F2: FENCE

L2: r2 = data1

L3: r3 = data2

其中FENCE指令保證前后的訪存指令順序一致。最后訪存指令的順序為:S1,S2->F1->S3->L1->F2->L2,L3,結果(r1, r2, r3) = (SET, NEW, NEW)。

如果中間的FENCE指令去掉,那么可能會出現r2和r3為0的情況。

二、loongarch內存模型相關信息

1、loongarch內存一致性模型

根據loongarch架構手冊中相關信息,其采用弱一致性(Weakly Consistency)的模型。在該模型下,程序員必須通過同步指令將對寫共享單元的訪問保護起來,以保證多個處理器核對于寫共享單元的訪問是互斥的。

雖然目前的資料中無法得知loongarch內存一致性模型的具體信息,但可以推測其應該打亂了一些訪存指令的順序,需要借助柵障指令(即fence或barrier指令)進行同步。

2、loongarch內存訪問類型

loongarch架構下有三種內存訪問類型:

  • 一致可緩存(Coherent Cached)
  • 強序非緩存(Strongly-ordered UnCached)
  • 弱序非緩存(Weakly-ordered UnCached)

例如,在頁表項中的MAT(Memory Access Type)域中可以設置對應內存區域的訪問類型。MAT值與內存訪問類型的關系如下:

  • 0對應強序非緩存
  • 1對應一致可緩存
  • 2對應弱序非緩存
  • 3為保留

通過設置內存訪問類型,相當于規定了一片內存區域的內存一致性模型。loongarch手冊資料中指出,只有強序非緩存沒有副作用,即不打亂訪存指令的順序。

不過loongarch資料中內存一致性模型和內存訪問類型并沒有詳細解釋,很多地方存在疑點,只能推測其作用類似于arm上的Normal、Device、Strongly-ordered幾種內存模型。

三、loongarch相關指令

1、柵障指令

loongarch中柵障指令如下:

  • dbar指令:dbar hint。dbar指令用于完成load/store訪存操作之間的柵障功能,其中hint用于指示dbar指令的同步對象和同步程度。hint為0在loongarch中是必須實現的,如果沒有專門的功能實現,其他所有的hint值都將視為hint=0執行。hint為0指示一個完全功能的同步柵障,只有等到之前所有load/store操作執行完后,dbar 0才會執行;且只有dbar 0執行后,其后所有的load/store操作才能執行。
  • ibar指令:ibar hint。ibar指令用于完成單個處理器核內部store操作和取指操作之間的同步,其中hint用于指示dbar指令的同步對象和同步程度。同樣的,hint為0在loongarch中是必須實現的。ibar 0確保其后的取指一定能夠觀察到ibar 0指令之前所有store操作的執行效果。

2、 原子指令

loongarch中原子指令如下:

  • amswap、amadd、ammax等指令:普通原子指令,能夠原子地完成對某個內存單元的“讀-修改-寫”過程。如amadd.w rd, rk, rj表示將rj寄存器值作為地址,從該地址讀取值寫入rd,然后將rd與rk進行加法操作,最后將結果寫回該地址,rd中保存該地址中的舊值。整個過程是原子的。
  • amswap_db、amadd_db、ammax_db等指令:帶數據柵障功能的原子指令。除了和上面普通原子指令的功能外,還有dbar指令的效果。
  • ll/sc指令:ll/sc一對指令能夠完成“讀-修改-寫”原子操作。
    其作用機制為:ll指令能夠完成讀操作,并同時記錄訪問地址和在相關寄存器中置上一個標記(LLbit置為1)。sc指令能夠完成寫操作,并會先檢查寄存器中的LLbit,只有當LLbit為1時才進行寫入。而ll和sc之間的指令完成自定義的修改操作。
    在ll/sc指令期間,如果其他處理器核中對該ll/sc指令操作的相同地址進行了寫入,那么LLbit就會被清0,這樣sc指令也會返回失敗。這樣的硬件檢查機制保證了原子性。
    另外,ll/sc指令也有柵障功能。
    具體使用方法參見下文中spinlock實現。

loongarch原子指令的特點與一些RISC架構的原子指令相似,也類似的用ll/sc這樣的指令來代替了CAS(compare-and-swap)類型原子指令。ll/sc指令相比于CAS類指令,CAS指令實現鎖時可能會有ABA問題,而使用ll/sc指令可以避免這個問題。

四、應用場景:spinlock

下面通過spinlock的實現,說明原子指令和柵障指令的應用。

作為對比,首先介紹linux3.2中arm下spinlock的實現。

lock操作函數如下:

static inline void arch_spin_lock(arch_spinlock_t *lock)
{
unsigned long tmp;

__asm__ __volatile__(
// 將lock->lock加載到tmp,ldrex和strex為一對原子指令
// lock是函數參數,lock->lock為整型數據
"1: ldrex %0, [%1]\n"
// 判斷tmp是否為0
" teq %0, #0\n"

// 失敗則執行wfe,等待事件將其喚醒
WFE("ne")
| // 省略了一些實現細節
|-> #define WFE(cond) ALT_SMP("wfe" cond, "nop")

// 成功則將1寫入lock->lock,strexeq的結果保存在tmp
" strexeq %0, %2, [%1]\n"
// 判斷tmp的值,如果strexeq成功,tmp為0,否則為1
" teqeq %0, #0\n"

// 如果strexeq失敗,則跳轉到前面標簽1,ldrex指令處
" bne 1b"
: "=&r" (tmp)
: "r" (&lock->lock), "r" (1)
: "cc");

// barrier指令
smp_mb();
}

unlock操作函數如下:

static inline void arch_spin_unlock(arch_spinlock_t *lock)
{
// barrier指令
smp_mb();

// 簡單的將lock->lock置1
__asm__ __volatile__(
" str %1, [%0]\n"
:
: "r" (&lock->lock), "r" (0)
: "cc");

// dsb和sev指令
// dsb為barrier,保證str執行完畢后才執行sev
// sev發送事件喚醒正在等待事件的cpu核
dsb_sev();
}

可以看到,arm中也有類似的原子指令和柵障指令。其中ldrex/strex指令類似于loongarch中的ll/sc指令。并且lock和unlock函數之后均有柵障指令進行同步。

類似地,loongarch中spinlock也可以仿照上述代碼實現:

spin_lock:
// 將lock值加載到寄存器t0,假設參數寄存器a0中為傳入的參數lock
1: ll.d t0, a0, 0
// 如果lock不為0則跳轉
bnez t0, 1b

// 將t0置1并寫入lock表示上鎖,t0保存sc執行結果
li.d t0, 1
sc.d t0, a0, 0

// 如果sc失敗則跳轉
bnez t0, 1b

// barrier
dbar 0
spin_unlock:
dbar 0
// 將參數lock寫入0
st.d zero, a0, 0

總結

本文介紹了內存一致性模型、loongarch架構中內存一致性模型相關信息、原子指令和柵障指令的含義和使用方法,并結合自旋鎖的案例進行了說明。同時發現,因為目前市場上得到的資料有限,loongarch架構內存一致性模型中還有一些不清楚的地方,需要后面相關廠家完善。

??想了解更多關于開源的內容,請訪問:??

??51CTO 開源基礎軟件社區??

??https://ost.51cto.com??

責任編輯:jianghua 來源: 51CTO 開源基礎軟件社區
相關推薦

2022-12-15 17:31:41

架構龍芯

2023-02-03 14:41:03

地址翻譯模式loongarch

2023-03-01 14:59:08

TLB維護架構

2023-02-21 16:46:04

loongarch架構

2011-11-07 10:21:36

VPSVPN

2010-04-02 16:53:34

Oracle內存結構

2009-09-02 09:44:01

JSP和JavaBea

2018-11-06 12:12:00

MySQL內存排查

2009-11-25 11:14:12

PHP二維數組賦值

2009-12-11 15:59:00

Linux grep指

2009-12-25 14:24:59

Linux指令od

2011-06-21 10:17:41

c++內存模型

2021-09-04 00:03:30

AMDCPU架構

2009-06-03 14:36:03

Struts簡介

2009-07-03 10:19:29

JSP相關軟件

2023-12-10 16:48:00

Wasm瀏覽器

2013-07-19 13:16:26

iOS中BlockiOS開發學習內存管理

2010-06-29 15:51:22

Linux SNMP協

2016-09-26 17:09:28

Java并發編程內存模型

2022-10-08 11:16:04

UbuntuLoongArch
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美aaaa视频 | 免费成人高清 | 精品久久一区二区三区 | 国产午夜精品视频 | 91天堂网 | 午夜99| 男女羞羞免费视频 | 日韩久久久久久久 | 亚洲国产精品一区二区久久 | 九九久久精品视频 | 国产激情网站 | av在线一区二区三区 | 国产中文区二幕区2012 | 精品国产精品 | 日韩免费av网站 | 成人三级在线观看 | 国产一区二区三区www | 美国av毛片| 国产精品久久久久久亚洲调教 | 亚洲午夜三级 | 精品国产一区二区三区性色av | 亚洲国产欧美91 | 亚洲永久 | 在线免费观看黄色 | 亚洲一区电影 | 国产成人久久精品一区二区三区 | 天天干 夜夜操 | 国产精品免费av | 欧美一级黄 | 三级国产三级在线 | 精品国产视频 | 在线日韩 | 在线一区| 国产毛片av| 播放一级黄色片 | 99热精品在线 | 国产一级一级毛片 | 在线观看成人小视频 | 91视频在线观看 | 久久男人| 91精品国模一区二区三区 |