#RISC-V弱内存模型

这里RISC-V内存模型为了保证执行顺序和程序的一致性,利用了四大类,13个规则。这里下面的指令是指访存指令,我们可以看看下面的规则,如何保证执行时保证前后两条访存的顺序。

重叠地址

一、 store 在后

不像TSO对于store的顺序要求很严格,这里只要求对于同一个地址的顺序。

a) load/store  addr0
b) store addr0

对于后面bstore的情况,我们必须保证这个顺序。

二、CoRR

对于两条load之间没有写指令的情况,我们保证后一个load不会读取到更老的值。

a) load a0,addr0
b) load a1,addr0

即使其他核上对addr0,进行了写入,也只可能让b读取到更新的值。

三、原子指令

前一个指令是原子指令,后一条指令是读取,那么后一条指令一定能读取到前一条指令写入的值。

显示同步

四、FENCE指令

如果两条访存指令之间有一条fence指令,那么必须根据fence的要求进行顺序的确定。

五、acquire

如果前一条指令有acquire,那么必须要求后面的指令不能超前。

六、release

如果后面一条指令有release,那么要求前面的指令不能延后。

七、两条指令都有acquire和release标志

当然也必须顺序

八、LR/SC

这里LRLoad reservedSCstore condition,会要求只用先进行LR之后才能
SC

语法依赖

语法依赖感觉有点像流水线中的依赖关系

  • 九,后一条指令的地址依赖于前一条指令
  • 十,后一条指令的数据依赖于前一条指令
  • 十一,后一条指令在控制流上依赖前一条指令,即一个分支是否流向了后一条指令。

流水线依赖

十二

a) store/load 
<memory operation depend on a>
b) load value stored by last memory op

十三

a) load/store
<memory operation address depend on a>
b) store

例子

int x = 0;
int y = 0;

void t1() {
    y = 1;
    int res = x;
    printf("x=%d\n", res);
}

void t2() {
    x = 1;
    int res = y;
    printf("y=%d\n",res);
}

这个程序在x86上会出现0, 0的情况,因为它是TSO, 在如上的RISC-V机器上也可能出现。

Sequential Consistency

在程序顺序上的前后,在插入全局内存序,依旧保持,而且部分是否是同一地址。
但是SC也无法保证不同核上程序之间到底是什么顺序,我们可能需要一些原子指令。

int sum  = 0;
void t1() {
    sum += 1;
}
void t2() {
    sum += 2;
}

这个程序由于没有原子性的保证所以,结果可能不是3。在RISC-V中,我们可以使用LRSC进行。

TSO

在流水线设计中,我们往往会加入一个store buffer, load可以使用buffer转发的方式获取最新的值,store buffer大大提高了外设和内存的访问效率。当然如果是外设的情况,不能进行转发,因为IO必须保证顺序。
如果是这样,为了适应store buffer的加入,load就可以乱序到store前面,那么就有了TSO这种模型进行说明。