美文网首页
总线锁定和缓存锁定

总线锁定和缓存锁定

作者: 啊啊啊哼哼哼 | 来源:发表于2020-02-29 20:06 被阅读0次

    -总结自 “Java并发编程的艺术” 和以下两篇博客:
    https://blog.csdn.net/qq_35642036/article/details/82801708https://blog.csdn.net/martin_ke/article/details/88851393

    • 原子操作是指不可被中断的一个或者一组操作。
    • 处理器会自动保证基本的内存操作的原子性,也就是一个处理器从内存中读取或者写入一个字节时,其他内存是不能访问这个字节的内存地址。但处理器不能自动保证复杂的内存操作的原子性,比如跨总线宽度、跨多个缓存行或者跨页表的操作。
    • 总线锁定和缓存锁定是处理器保证复杂内存操作原子性的两个机制。

    总线锁定

    • 一个处理器在总线上输出LOCK#信号,使得其他处理器对内存的操作请求都会被阻塞,该处理器独占共享内存。

    缓存锁定

    • 由于总线缓存阻止了被阻塞处理器和所有内存之间的通信,而输出LOCK#信号的CPU可能只需要锁住特定的一块内存区域,因此总线锁定开销较大。
    • 缓存锁定是某个CPU对缓存数据进行更改时,会通知缓存了该数据的该数据的CPU抛弃缓存的数据或者从内存重新读取。

    MESI协议

    • MESI协议是经典的缓存一致性协议,它通过在每个缓存行要求设置两个状态位,使得每个缓存行处于M(modify), E(exclusive), S(share), I(invalid)四个状态之一。
    • M: 处于此状态的缓存数据,只有在本CPU中有,并且该数据已经被修改,与内存中的值不同;
    • E:独占的,只有本CPU有该缓存数据,并且与内存中数据一致;
    • S:共享的,多个CPU中都存有这个缓存数据,并且多个缓存数据和内存数据都是一致的;
    • I:该CPU存储的该缓存数据是无效的。
    • 一个处于M状态的缓存行,必须时刻监听试图读取该缓存行对应的主内存地址的操作,如果监听到,则必须在读取操作之前把缓存行的数据写回主内存。
    • 一个处于E状态的缓存行,必须时刻监听试图读取该缓存行对应的主内存地址的操作,如果监听到,则将缓存行状态置于I。
    • 一个处于S状态的缓存行,必须时刻监听使该缓存行无效或者独享该缓存行的请求,如果监听到,则必须把其缓存行状态设置为I。
    • 当一个CPU读取缓存行数据时,如果缓存行状态为I,则需要从内存重新读取,并把自己状态改为S。如果不为I可直接读取,但要必须要等待其他CPU的监听结果,如其他CPU也有该数据的缓存且状态是M,则需要等待其把缓存更新到内存之后,再读取。
    • 当CPU需要写数据时,只有缓存行状态为M或者E时才可以执行。否则需要发出特殊的RFO指令(Read Or Ownership,这是一种总线事务),通知其他CPU置缓存无效(I),这种情况下性能开销是相对较大的。在写入完成后,修改其缓存状态为M。

    两种不能使用缓存锁的情况

    • 第一种情况是操作的数据不能被缓存在处理器内部,或者操作的数据跨多个缓存行(cache line)时,则处理器会调用总线锁定。
    • 第二种情况是处理器不支持缓存锁定,对于Intel 486和Pentium处理器,就算锁定的内存区域在处理器的缓存行中也会调用总线锁定。

    相关文章

      网友评论

          本文标题:总线锁定和缓存锁定

          本文链接:https://www.haomeiwen.com/subject/jppmhhtx.html