1、前言
本文記錄一些RISC-V內(nèi)存操作在不同平臺(tái)、場(chǎng)景下的使用方式,方便代碼在不同平臺(tái)上的移植。
2、TSO操作映射
表1提供了從TSO內(nèi)存操作到RISC-V內(nèi)存指令的映射。
表1 從TSO操作到RISC-V操作的映射
正常的x86 load和store都是默認(rèn)帶有acquire-RCpc和release-RCpc操作:TSO默認(rèn)執(zhí)行所有的load-load、load-store和store-store排序。因此,在RVWMO下,所有TSO load必須映射到load + FENCE R,RW,所有TSO store必須映射到FENCE RW,W + store。
TSO原子讀-修改-寫和使用LOCK前綴的x86指令是完全有序的,可以通過同時(shí)具有aq和rl集的AMO實(shí)現(xiàn),也可以通過具有aq集的LR + 算術(shù)運(yùn)算 + 具有aq和rl集的SC以及檢查成功條件的條件分支來實(shí)現(xiàn)。在后一種情況下,LR上的rl注釋(由于不明顯的原因)是冗余的,可以省略。
TSO store可以通過rl集映射到AMOSWAP。然而,由于RVWMO PPO規(guī)則3禁止將AMOs的值轉(zhuǎn)發(fā)給后續(xù)load,因此將AMOs用于store可能會(huì)對(duì)性能產(chǎn)生負(fù)面影響。TSO load可以使用帶有aq集的LR進(jìn)行映射:所有這樣的LR指令都是不配對(duì)的,但這一事實(shí)本身并不排除對(duì)load使用LR。但是,如果這種映射對(duì)保留機(jī)制施加的壓力超過了最初的預(yù)期,那么它也可能對(duì)性能產(chǎn)生負(fù)面影響。
3、Power操作映射
表2提供了從Power內(nèi)存操作到RISC-V內(nèi)存指令的映射。Power ISYNC在RISC-V上映射到FENCE.I + FENCE R,R;后面的FNECE是必需的,因?yàn)镮SYNC用于定義RVWMO中不存在的“控制+控制FENCE”依賴關(guān)系。
表2 從Power操作到RISC-V操作的映射
4、Arm操作映射
表3提供了從ARM內(nèi)存操作到RISC-V內(nèi)存指令的映射。由于RISC-V目前沒有自帶aq或rl語義的普通load和store指令,ARM的load acquire和store release指令在RISC-V中用FENCE來映射。此外,為了確保store-release-to-load-acquire的順序,在store release和load acquire之間必須要有一個(gè)FENCE RW,RW。表3通過始終在每個(gè)acquire操作前防止FENCE指令來強(qiáng)制保證這一點(diǎn)。ARM的load-exclusive和store-exclusive指令通用可以映射到RISC-V上的LR和SC指令。但這里不需要把FENCE RW,RW放到帶aq的LR指令前面,而是直接使用aqrl。ARM ISB在RISC-V上映射到FENCE.I且后面跟著FENCE R,R指令。類似于ISYNC映射到Power的方式。不過ARM DSB如何映射到RISC-V上,這一點(diǎn)我暫時(shí)也沒想明白。
表3 從ARM操作到RISC-V操作的映射
5、Linux操作映射
表4提供了linux內(nèi)存排序宏到RISC-V內(nèi)存指令的映射。因?yàn)镽ISC-V Unix平臺(tái)需要一致的DMA,所以Linux的dma_rmb()和dma_wmb()分別映射到FENCE R,R和FENCE W,W。但如果在非一致的DMA平臺(tái)上,它們分別需要映射到FENCE RI,RI和FENCE WO,WO。具有非一致的DMA的平臺(tái)可能還需要一種機(jī)制,通過該機(jī)制可以使cache line失效,這些機(jī)制將是特定于設(shè)備或在ISA的未來擴(kuò)展中。
表4 從Linux內(nèi)存原語到RISC-V原語的映射
6、C語言映射
表5提供了C11/C++11原子操作到RISC-V內(nèi)存指令的映射。如果引入了帶有aq和rl語義的load和store,那可以使用表6的映射。但是要注意的是,只有當(dāng)atomic_(memory_order_seq_cst)使用集帶有aq和rl的LR進(jìn)行映射時(shí),這兩個(gè)映射才能正確互相操作。更重要的是,除非通過添加第二個(gè)FENCE或映射store為amoswap.rl來加強(qiáng)表5的store映射,不然表5的store和表6的load可以重新排序。
表5 從C/C++原語到RISC-V原語的映射
表6 如果引入load-acquire和store-release操作,從C/C++原語到RISC-V原語的映射
任何AMO操作都可以用LR/SC對(duì)來模擬,但必須注意確保任何源自LR的PPO順序也源自SC,并且任何終止于SC的PPO順序也終止于LR。例如,考慮到load操作沒有任何數(shù)據(jù)依賴關(guān)系的概念,還必須使LR遵循AMO擁有的任何數(shù)據(jù)依賴關(guān)系。同樣,在同一個(gè)hart的其它地方FENCE R,R的效果也必須適用于SC,否則SC不會(huì)遵守該FENCE的順序。不過仿真器可能可以通過簡(jiǎn)單地將AMO操作映射到lr.aq和sc,acrl來實(shí)現(xiàn)全有序原子操作的效果。
這些C11/C++11映射要求平臺(tái)為所有內(nèi)存提供以下物理內(nèi)存屬性(PMA, Physical Memory Attributes):
main memory
coherent
AMO Arithmetic
RsrvEventual
不過不同屬性的平臺(tái)可能需要不同的映射或者需要特定于平臺(tái)的軟件,例如Memory-mapped I/O。