RVWMO观他人博客总结
#RISC-V弱内存模型
这里RISC-V内存模型为了保证执行顺序和程序的一致性,利用了四大类,13个规则。这里下面的指令是指访存指令,我们可以看看下面的规则,如何保证执行时保证前后两条访存的顺序。
重叠地址
一、 store 在后
不像TSO对于store的顺序要求很严格,这里只要求对于同一个地址的顺序。
a) load/store addr0
b) store addr0
对于后面b是store的情况,我们必须保证这个顺序。
二、CoRR
对于两条load之间没有写指令的情况,我们保证后一个load不会读取到更老的值。
a) load a0,addr0
b) load a1,addr0
即使其他核上对addr0,进行了写入,也只可能让b读取到更新的值。
三、原子指令
前一个指令是原子指令,后一条指令是读取,那么后一条指令一定能读取到前一条指令写入的值。
显示同步
四、FENCE指令
如果两条访存指令之间有一条fence指令,那么必须根据fence的要求进行顺序的确定。
五、acquire
如果前一条指令有acquire,那么必须要求后面的指令不能超前。
六、release
如果后面一条指令有release,那么要求前面的指令不能延后。
七、两条指令都有acquire和release标志
当然也必须顺序
八、LR/SC
这里LR是Load reserved,SC是store 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中,我们可以使用LR和SC进行。
TSO
在流水线设计中,我们往往会加入一个store buffer, load可以使用buffer转发的方式获取最新的值,store buffer大大提高了外设和内存的访问效率。当然如果是外设的情况,不能进行转发,因为IO必须保证顺序。
如果是这样,为了适应store buffer的加入,load就可以乱序到store前面,那么就有了TSO这种模型进行说明。