受限事务内存/HTM 的详细工作原理是什么?

How does restricted transactional memory / HTM works in detail?

我正在学习硬件事务内存(HTM),但具体实现方式有限。 我知道 HTM 中的事务缓冲其在 L1cache 中设置的 read/write 并通过缓存一致性协议检测冲突。下面是我学习到的使用HTM的程序案例。

while (1) { // keep trying
    int status = _xbegin(); // set status = -1 and start transaction
    if (status == _XBEGIN_STARTED) { // status == XBEGIN_STARTED == -1
        (*a) ++; // non atomic increment of shared global variable
        (*b) ++;
        _xend(); // end transaction
        break; // break on success
    } else { //
        x_abort(0xff);
    } //
}

所以,我对“(*a)++”和“(*b)++”之间发生冲突时会发生什么感到困惑。说,T0增加了a,而T1读取了a。缓存协议会检测到冲突并中止 T0。但是 T0 会发生什么?它会保留 运行 其余代码,即 (*b)++ 和 _xend() 吗?我认为它不会保留 运行 而是会重试。但是它怎么知道循环的起点在哪里呢?这个具体是怎么实现的?

_xbegin() 具有非常特殊的语义。如果它成功地使线程进入事务状态,它 returns _XBEGIN_STARTED。进入事务状态有两件重要的事情:

  1. 在处理器上采用架构检查点。这基本上记录了架构寄存器和程序计数器的值。
  2. 内存操作变得推测性。在交易完成之前,商店是看不到的。这可以通过不同的方式实现,例如在本地缓存中缓冲存储或在保留撤消日志的同时将值写出到主内存。

如果在某个时候该事务中止(在您的示例中,T0 由于 read/write 与 T1 冲突而中止),首先丢弃所有推测内存操作,然后恢复体系结构检查点。后者确保 PC 在 int status = _xbegin(); 之后开始,但这次返回值 _XABORT_CONFLICT

您可以在博客文章 Arm’s Transactional Memory Extension support in gem5 中找到有关硬件事务内存实现的一些信息。如果您对细节感兴趣,值得花一些时间阅读 gem5/Ruby 源代码。