首页 > 解决方案 > 如何将 Intel TSX 与 C++ 内存模型一起使用?

问题描述

我认为 C++ 还没有涵盖任何类型的事务内存,但 TSX 仍然可以以某种方式使用“好像规则”来适应由 C++ 内存模型管理的东西。

那么,成功的 HLE 操作或成功的 RTM 事务会发生什么?

说“存在数据竞争,但没关系”并没有多大帮助,因为它没有阐明“好的”是什么意思。

使用 HLE 可能可以将其视为“先前的操作发生在后续操作之前。就好像该部分仍然被被省略的锁所保护”。

RTM 是什么?因为甚至没有省略的锁,只有(可能是非原子的)内存操作,可以是加载、存储、两者,或无操作。什么与什么同步?在什么之前会发生什么?

标签: c++language-lawyermemory-modelintel-tsx

解决方案


显然,在进入规格或询问之前,我应该彻底阅读“概述”页面:

硬件锁省略概述

即使省略处理器没有对锁执行外部写操作,硬件也能确保程序对锁的操作顺序。如果省略处理器本身在临界区读取锁的值,则看起来好像处理器已经获得了锁(读取将返回未省略的值)。此行为使 HLE 执行在功能上等同于没有 HLE 前缀的执行。

受限事务内存概述

RTM 内存排序

成功的 RTM 提交会导致 RTM 区域中的所有内存操作看起来都以原子方式执行。由 XBEGIN 后跟 XEND 组成的成功提交的 RTM 区域,即使在 RTM 区域中没有内存操作,也具有与 LOCK 前缀指令相同的排序语义。XBEGIN 指令没有防护语义。但是,如果 RTM 执行中止,来自 RTM 区域内的所有内存更新都将被丢弃,并且永远不会对任何其他逻辑处理器可见。

要完成答案:

LOCK前缀指令映射到 C++ std::memory_order::seq_cst。这涵盖了所有成功的 RTM 事务(就像单LOCK前缀指令一样)。它还涵盖了大多数 HLE 案例。具体来说:

  • LOCK前缀指令的执行就像它们被执行一样,这seq_cst也意味着
  • XACQUIRE XCHG/相同XRELEASE XCHG,就好像它被执行一样,这seq_cst也意味着
  • 最后,XRELEASE MOV [mem], op好像MOV [mem], op,所以它只是release(在 C++ 内存模型的通常实现下,顺序一致的存储有内存栅栏,而不是加载)

(文档链接适用于英特尔编译器。但是它们记录了硬件行为,因此这些信息应该适用于其他编译器。编译器可能引入的唯一变量是编译时重新排序。但是我希望如果编译器实现内在的,它也实现了正确的重新排序禁止,如果仍然不确定,放置编译器障碍。直接汇编应该只相应地标记汇编代码)


推荐阅读