计算机体系结构——多线程(核)访存“上锁”——原子指令

1. 原子性存储器访存操作

如果存储器操作为所有core(线程)知道,那就称为原子性(Atomic)共享存储器访问操作。原子指令虽然不是一种同步操作,但能够使各线程可以同步的访问存储器。

2. “锁”的概念

  • 定义

假设一个场景如core1,core2共享一片数据区间,但是同一时间只有一个core能够独占此数据区间,为避免两core同时发送请求导致竞争现象,于是二者约定了一个共享的全局变量作为“锁”,使得在进行存储器原子读和原子写操作时任何其他操作都不得插入。通常,体系设计人员并不希望基本硬件原语被用户使用,而希望这些原语被系统设计者用来建立同步库。

  • “上锁”过程

该变量在硬件上的本质是在存储器中分配一个地址保存该变量的值(core1和core2均能访问)。
1)当某个core独占共享数据区并完成相关操作后,便会释放该数据区,通过向锁中写0将其释放。
2)没有独占数据区的core都会不断的读锁中的值,判断是否空闲。若读到的值为0(空闲),便会向锁中写入1进行上锁

3. RSIC-V指令集中的实现

以RISC-V指令集RV32I指令格式为例。

  • 原子性fetch-and-op存储器指令(AMO)

    为解决上述竞争问题,可引入原子操作,即第一次读(发现锁空闲)和下一次写操作(写入1)成为一个整体,这样当发送读请求的后即上锁,其他core的请求便无效,即读出-计算-写回。
    计算机体系结构——多线程(核)访存“上锁”——原子指令_第1张图片
    (AMO也支持释放一致性模型)
  1. 执行过程
    使用原子指令将锁中的值读出,并向锁中写入数值1。该过程为一个整体性的原子操作,读和写操作间其他核不会访问到锁其他core读锁值,若为1则继续扫描读值,若为0,尝试加锁,向该锁变量写入1进行独占。

    例如amoadd.w rd, rs2, (rs1)   该指令用于从地址为寄存器rs1值的存储器中读出一个值,存放到rd寄存器中,并且将读出的数据与rs2寄存器值进行计算(相加),将结果存放到rd寄存器中
  • 互斥操作(LR/SC指令)

    虽然原子操作能解决多线程的竞争问题,但由于会将总线锁住,导致其他核无法访问总线,在核数众多且频发抢锁的情况下,会造成总线长期被锁的情况,因此引入一种新的互斥类型的存储器访问指令,即LR(load reserved)/SC(store conditional)指令。
    计算机体系结构——多线程(核)访存“上锁”——原子指令_第2张图片
    (LR/SC也支持释放一致性模型)
  1. 执行流程
    LR指令从存储器中读一个数值,同时处理器会监视这个存储器地址,看它是否会被其他处理器修改;SC指令发现在此器件没有其他处理器修改该值,则将新值写入该地址。因此一个原子的LR/SC指令对,就是LR读取值,进行一些计算,然后试图保存新值,如果保存失败,则需重新开始整个序列。可总结为:LR -> load/store ->SC。因此成对的LR和SC操作之间并不会将总线锁住,也就不会导致系统性能的下降。

    LR指令用于从存储器(地址为rs1寄存器的值指定)中读一个长度为XLEN的数据存放到rd寄存器中。
    SC指令用于向存储器(地址为rs1寄存器的值指定)中写入一个长度为XLEN的数据,数据的值来自于rs2寄存器中的值。即保存寄存器的值,且如果执行成功则将寄存器的值修改为1, 如果失败则修改为0。如果LR指令返回锁单元的原始值,SC执行成功时才会返回1。
  2. LR/SC执行成功的条件
    一般要顺序的使用这两条指令,如果LR指令所指定的锁单元的内容在相同地址的SC指令执行前已被改变,那么SC指令就执行失败,也就是说SC指令需要一定条件才能执行成功:
    1)LR/SC成对访问相同地址;
    2)LR/SC间没有任何其他的写操作(来自于任何一个hart)访问过相同的地址;
    3)LR/SC指令间没有中断核异常发生;
    4)LR/SC访问存储器地址必须地址对齐,否则会产生地址非对齐异常;
    5)LR/SC间没有执行MRET指令

    如果执行成功则向rd寄存器写回数值0;若失败则向rd寄存器写回一个非零值。

    实际上允许使用的并且不会造成问题的只有寄存器-寄存器指令,而处理器可能由于重复的页错误而导致始终无法完成SC指令,从而使处理器处于一种死锁的状态,另外,LR和SC间的指令数一定要尽可能少,这样才可以减少不相关的事情或者竞争资源的处理器所引SC执行失败的频率。
  3. LR/SC的优点
    可以通过LR/SC构造其他的诸如原子比较和交换或者原子取后加等同步用语,这些同步用语可以用在一些并行编程模型中,这些同步用语的实现需要在LR/SC指令间插入更多的指令,但不需要太多。

 

 

你可能感兴趣的:(计算机结构)