2

假设您有两个线程,一个创建 TSX 事务,并修改一些数据结构。另一个线程不进行任何类型的同步并读取相同的数据结构。事务对它来说是原子的吗?我实际上无法想象这可能是真的,因为如果它尝试读取由事务修改的缓存行,则无法阻止或重新启动它。

如果事务不是原子的,那么 x86 上的写入顺序规则是否仍然受到尊重?如果它看到了写#2,那么保证它必须能够看到之前的写#1。这仍然适用于作为事务的一部分发生的写入吗?

我在任何地方都找不到这些问题的答案,而且我有点怀疑 SO 上的任何人都会知道,但至少当有人发现这是一个谷歌友好的地方来提供答案时。

4

1 回答 1

3

(我的答案基于Intel® 64 and IA-32 Architectures Optimization Reference Manual,第 12 章)

事务对于读取来说是原子的,因为读取将导致事务中止,因此看起来它从未发生过。在事务区域中,读取的高速缓存行(在 L1 中跟踪)被认为是读取集,而从写入集中写入的行。如果另一个处理器从写入集(这是您的示例)读取或写入读取集或写入集,则存在数据冲突。

通过缓存一致性协议检测数据冲突。数据冲突导致事务中止。在初始实现中,检测到数据冲突的线程将事务性中止。

因此,尝试事务的线程正在跟踪该行,并在另一个线程发出其读取请求时检测到冲突。它中止并且“硬件将在 XBEGIN 指令的操作提供的指令地址处重新启动”。在本章中,没有关于第二个处理器在做什么的区别。无论是尝试事务还是执行简单读取都没有关系。

总而言之,所有线程(无论是否事务)要么看到完整的事务,要么什么也没有。只有 TSX 事务中的线程才能看到内存的中间状态。

于 2014-03-23T17:03:35.763 回答