在MIPS中实现原子操作
一、详解原子操作
1、原子操作的特点
①不可中断性:一旦开始,就不会被其他操作打断直到完成。
②完整性:操作要么完全执行,要么完全不执行,没有中间状态。
③独立性:执行结果不依赖于线程的调度方式或者操作的交错执行。
即原子操作是一个不可分的操作
2、为什么要实现原子操作
在多个进程同时对一个内存单元进行操作的时候,如果任务之间不进行同步,就会有数据竞争的风险。举个例子,例如
A和B都需要对寄存器s0进行+1的操作,即最终我们希望s0最后会+2。
A从寄存器中取出了一个数据0;
B从寄存器中取出了一个数据0;
A对取出的数据+1;
B对取出的数据+1;
A放回数据,s0的值为1;
B放回数据,s0的值为1;在这个过程中,由于+1这个操作不是原子的,导致A的操作被B覆盖了,如果我们将这个+1的操作原子化,将取数据,+1,放回数据合并成一个不可再分的原子化操作,那么我们就可以避免数据冲突。
(至于为什么不直接用addi,是因为很多时候我们需要取数据+操作+放回数据而不是直接修改数据,这里的+1只是模拟这个过程)
二、原子操作的实现
1、链接取数指令和条件存数指令
①链接取数指令
示例:ll $t1,0($s1)
含义:LL指令从内存$s1中读取一个字,并将其加载到寄存器$t1中。与普通的加载指令(如LW)不同,LL指令还会在内部记录加载的内存地址和对应的数据,为后续的SC指令做准备。
②条件存数指令
示例:sc $t1,0($s1)
含义:SC指令试图将一个寄存器$t1中的值写入到内存$s1中。但是,SC会根据上一个保存有相同地址的LL指令判断有没有其他处理器在LL和SC指令之间修改过该内存位置,如果没有才会写入成功。如果写入成功,SC指令将在目标寄存器$t1中写入0;如果失败(即在这段时间内内存位置被修改),则写入1。
2、示范
接下来,让我们示范如何实现+1操作的原子化。
again:ll $t0,0,($s0)
addi $t0,$t0,1
sc $t0,0($s0)
beq $t0,$zero,again
在上述代码中,我们先从s0中取出一个数,然后自加1后用sc放入原寄存器,若在此过程中没有其他处理器修改过该内存,则t0为1,执行成功。否则t0为0,跳转到again重新执行,在这个过程中,自加1操作不再可分。
2514

被折叠的 条评论
为什么被折叠?



