java - CPMXCG(比较和交换)在多处理器机器上到底如何工作?

标签 java assembly lockless

想象一个场景: 2 个核心同时执行 CaS 操作。处理器需要读取旧值,然后放置新值,IN 旧值是相同的。如果他们同时阅读怎么办?或者是否对变量施加了任何类型的锁定,以防止其他核心读取?

最佳答案

是的,在大多数架构上,每个核心都会尝试“读取所有权”流程,这意味着它仅出于更改目的而请求该行。其中一个会获胜,将数据发送回请求核心并以某种方式阻止另一个请求或回收。确切的细节取决于设计,但一般来说,您可以期望获胜的核心消耗数据并将其原子地更改为新值(通过内部锁定,因此在该过程中不会受到干扰),然后完成对新数据进行写回或内部缓存(处于修改状态)的操作。

此时,另一个请求可能会继续并尝试获取该线路的所有权 - 如果该线路仍保留在第一个核心中,则将导致窥探读取修改后的数据。然后第二个核心可以重复与第一个核心相同的过程。

在更简单的系统上,可以通过在此过程中停止所有内存事务来实现相同的目的(“总线锁”,如 Egor 提到的),但现在这种情况非常罕见,因为性能很糟糕,因此它保留用于非常复杂的情况就像变量未对齐并且数据在两行之间分割时一样。

请注意,关键部分(CaS)理想情况下应该在核心内部完成,其中本地缓存行锁可以保持原子性(在锁定该行时没有其他人可以读取该行或取得该行的所有权),而其他内核可以访问其他内存地址,而不会丢失一致性或原子性。

关于java - CPMXCG(比较和交换)在多处理器机器上到底如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22518710/

相关文章:

将 C 代码转换为汇编代码

c++ - 用32位原子实现64位原子计数器

c# - 线程安全的通用字段

java - 异步任务上的多个notifyObservers()不起作用

java - 如何使用 @GET 从 RESTful 服务响应 List<>

java - Hibernate 和 NonUniqueObjectException

c - 我应该如何在不使用锁的情况下在另一个线程的回调中注册更新?

java - 用 java 编写这个 python 结构

c++ - 进一步了解 i++ 和 i=i+1

assembly - ASM 8086 没有分区的分区