01、前言
RISC-V的RVWMO模型主要包含了preserved program order、load value axiom、atomicity axiom、progress axiom和I/O Ordering。今天主要記錄下preserved program order(保留程序順序)中的Explicit Synchronization(顯示同步)。
02、顯式同步
顯示同步指的是:a操作在程序順序中先于b操作,a和b都訪問常規(guī)主存,不是I/O區(qū)域,如果存在以下任何一個條件,那么a操作和b操作在全局內存順序中的順序也不會變。
a和b之間有FENCE指令。
a擁有acquire語義。
b擁有release語義。
a和b都有RCsc語義。
a和b是配對的。
關于第一點:默認情況下,F(xiàn)ENCE指令確保所有在程序順序中位于FENCE之前的指令的內存訪問(“前導集”)在全局內存順序中比在程序順序中位于FENCE之后的指令的內存訪問(“后續(xù)集”)出現(xiàn)得更早。不過,為了性能上的考量,F(xiàn)ENCE可以選擇性進一步地限制前導集和后續(xù)集為較小的內存訪問集。具體來說,F(xiàn)ENCE有PR、PW、SR和SW bits,它們限制了前導集和后續(xù)集所包含的指令類型。如果PR為1,那么前導集包括load;如果PW為1,那么前導集包含store;如果SR為1,那么后續(xù)集包括load;如果SW為1,那么后續(xù)集包括store。
FENCE中PR、PW、SR和SW這4bit可以組成16種FENCE語義,但不是每一種組合都有用的。其中有7中組合具有空的前導集或后續(xù)集,因此是無操作的。另外FENCE還有一個額外的編碼為FENCE.TSO,提供它主要是方便映射到“acquire+release”或RVTSO語義上。不過在這10(16-7+1)個選項中,只有下面6個在實踐中常用:
FENCE RW,RW
FENCE.TSO
FENCE RW,W
ENCE R,RW
·FENCE R,R
FENCE W,W
RISC-V手冊建議程序員只使用這6種FENCE指令,其他組合的FENCE指令可能不生效,而且會造成意外的結果。
關于第二點:通常在關鍵代碼的臨界區(qū)開始時使用acquire操作,要求在程序順序在acquire之后的load和store操作也要在全局內存順序上在acquire之后。這樣可以確保關鍵代碼臨界區(qū)內位于acquire操作之后的所有l(wèi)oad和store可以獲取最新的數(shù)據(jù)。Acquire操作排序可以通過兩種方式來實現(xiàn)。
使用acquire語義的指令:它只針對同步變量本身強制排序
使用FENCE R,RW:它針對之前的所有l(wèi)oad強制排序
如下代碼1使用第一種方案,因為amoswap使用了aq,所以臨界區(qū)的load和store保證出現(xiàn)于獲取鎖的amoswwap之后的全局內存順序中。然而a1和a2指向不同的內存位置,臨界區(qū)的load和store可能與它們亂序,也就是在全局內存順序中,它們之間的順序不是固定的。
如下代碼2使用第二種方案,在這種情況下,盡管amoswap不強制使用aq進行排序,但FENCE仍然強制amoswap在全局內存順序中出現(xiàn)的時間比臨界區(qū)中的所有l(wèi)oad和store都要早。但使用FENCE的一個副作用就是,F(xiàn)ENCE還強制執(zhí)行了額外的排序,它還要求程序開始時的a2不相關的load指令出現(xiàn)的時間要早于臨界區(qū)的load和store。因此,F(xiàn)ENCE命令比aq命令在排序上更強硬些,當然也更粗糙些。
關于第三點:Release排序和acquire排序的工作原理類似,只是排序的方向相反。Release語義要求在release操作程序順序之前的所有l(wèi)oad和store也要在全局內存順序上先于release操作。這樣可以確保在全局內存順序中,臨界區(qū)的內存訪問出現(xiàn)在release釋放鎖的store之前。就像acquire語義一樣,release語義可以通過兩種方式來實現(xiàn):
使用帶release的指令
使用FENCE RW,W指令
例子就如同第二點中代碼1和代碼2。代碼1在關鍵代碼片段的末尾使用rl來確保順序,其中a3和a4與rl之間沒有固定關系,在全局內存順序上沒有固定順序。代碼2在關鍵片段的末尾使用FENCE RW,W來確保順序。
關于第四點:如果單獨使用RCpc語義,就不會強制store release到load acquire的順序,這有助于移植在TSO或RCpc內存模型下編寫的代碼。為了確保store release到load acquire的順序,代碼必須使用RCsc的語義。
關于第五點:在全局內存順序中,SC必須出現(xiàn)在與其配對的LR之后。由于固有的語法數(shù)據(jù)依賴,通常使用LR/SC來執(zhí)行原子讀-修改-寫操作。但其實即使store的值在語法上不依賴于成對LR返回的值,這一點也適用。