处理器如何实现原子操作

首先处理器会自动保证基本内存操作的原子性。处理器保证从系统内存中读取或者写 入一个字节是原子的,意思是当一个处理器读取一个字节时,其他处理器不能访问这个字节 的内存地址。最新的处理器能自动保证单处理器对同一个缓存行里进行16/32/64位的操作是原子的,但是复杂的内存操作处理器是不能自动保证其原子性的,比如跨总线宽度、跨多个缓存行和跨页表的访问。但是,处理器提供总线锁定和缓存锁定两个机制来保证复杂内存操作的原子性。

1 使用总线锁保证原子性
举一个例子

 

CUP1,CPU2,CPU3从内存中读取i,各自加1后写入内存中。上述操作是在各自CPU内进行的操作,没有保证操作的原子性。如果想要保证操作的原子性,就意为着其中一个CPU在进行操作时,其它的CPU不能进行操作,需要等待。

处理器的总线锁就是来解决这个问题的。什么是总线锁呢?

如果说主板是一座城市,那么总线就像是城市里的公共汽车,能按照固定行车路线,传输来回不停运作的比特。这些线路在同一时间内都仅能负责传输一个比特。标红的这句话很重要,要考的,要考的,要考的。它就是实现原子操作的关键元素之一。一句话:总线就是连接各个部件的信息传输线,是各个部件共享的传输介质,同一时间只负责传输一个比特。

总线说完了后,来说说总线锁。

总线锁就是使用处理器提供的一个 LOCK#信号,当其中一个处理器在总线上输出此信号时,其它处理器的请求将被阻塞住,那么该处理器可以独占共享内存。

说到这里,大家也明白了总线锁定。但总线锁定的开销太大,因为总线锁定期间,其它处理器不能操作其它内存地址的数据。所以,下面会说到使用缓存锁来保证原子性。

2 使用缓存锁保证原子性
事实上保证操作的原子性,就是保障数据在内存中的变化。在同一时刻,我们只需要保证对某个内存地址的操作是原子性即可。

上面说到了总线锁定的开销比较大,所以,目前处理器在某些场合下使用缓存锁定代替总线锁定来进行优化。

这里所说的缓存是指计算机CPU的高速缓存(L1,L2,L3)。在处理器准备进行处理的时候,一般会将要处理的数据预加载到高速缓存中,频繁使用的内存也会在高速缓存中。处理器处理数据会先进入高速缓存中查找,没有找到再去内存中。高速缓存的命中率很高,基本不需要到内存中查找。

所谓“缓存锁定”是指内存区域如果被缓存在处理器的缓存行中,并且在Lock操作期间被锁定,那么当它执行锁操作回写到内存时,处理器不会在总线上声言LOCK#信号(总线锁定信号),而是修改内部的内存地址,并允许它的缓存一致性机制来保证操作的原子性,因为缓存一致性机制会阻止同时修改由两个以上处理器缓存的内存区域数据,当其他处理器回写已被锁定的缓存行的数据时,会使缓存行无效。

3 缓存锁定不能使用的特殊情况
第一种情况是:当操作的数据不能被缓存在处理器内部,或操作的数据跨多个缓存行 时,则处理器会调用总线锁定。

第二种情况是:有些处理器不支持缓存锁定。
————————————————
版权声明:本文为CSDN博主「许洪昌」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/love1793912554/java/article/details/97616752

原文地址:https://www.cnblogs.com/wwkk/p/13290478.html