【问题标题】:Does an aborted xbegin transaction restore the stack context that existed at the xbegin start?中止的 xbegin 事务是否会恢复 xbegin 开始时存在的堆栈上下文?
【发布时间】:2016-08-22 06:04:25
【问题描述】:

我对在静态汇编程序库中的 XBEGIN( ) 和 XEND( ) 函数中封装事务性 xbegin 和 xend 感兴趣。但是,考虑到源自其他堆栈级别(更高或更低)的 xabort,我不清楚堆栈如何(或是否)恢复到原始 xbegin 调用状态。换句话说,动态堆栈上下文(包括中断效果)是否只是作为事务的另一部分进行管理和回滚?

VC++ 2010 构建不支持或不支持 _xbegin( ) 和 _xend( ) 内部函数,并且 x64 构建不能使用 _asm { } 内联。

【问题讨论】:

    标签: c++ x86 intrinsics intel-tsx


    【解决方案1】:

    相关:另请参阅 David Kanter's TSX writeup 了解有关它如何在后台工作以及软件如何从中受益的一些理论,以及 this blog post 了解 HSW 上的一些实验性能数据(在发现 TSX 错误和禁用微码更新之前TSX 在那个硬件上。)


    英特尔 insn 参考手册entry for xbegin 非常清楚。 (请参阅 标签 wiki,获取英特尔官方 PDF 和其他内容的链接。)

    在 RTM 中止时,逻辑处理器丢弃 所有架构 在 RTM 执行期间执行的寄存器和内存更新 将架构状态恢复到与最外层对应的状态 XBEGIN 指令。中止后的回退地址是根据最外面的 XBEGIN 指令计算的。

    因此该指令的工作方式类似于条件分支,其中分支条件是“在XEND 之前发生中止吗?”例如:

    ; NASM syntax, I assume MASM is similar
    ALIGN 16
    retry:
        ; eax holds abort info, all other architectural state + memory is unchanged
        inc     [retry_count]      ; or whatever other debug instrumentation you want to add
    
    global xbegin_wrapper_with_retry
    xbegin_wrapper_with_retry:
        xbegin  retry
        ret
    

    如果发生中止,就好像在xbegin 之后运行的所有代码根本没有运行,只是跳转到修改了eax 的后备地址。

    当然,您可能想要做的不仅仅是在中止时无限重试。这并不是一个真实的例子。 (This article 确实有一个你可能想要使用的逻辑的真实示例,使用内在函数。看起来他们只是测试eax 而不是使用xbegin 作为if 中的跳转,除非编译器会优化该检查。IDK 如果它是最有效的方法。)

    “中断效果”是什么意思?在当前的实现中,任何改变特权级别的事情(如系统调用或中断)都会导致事务中止。因此,环形级别的更改永远不需要回滚。 CPU 在遇到无法回滚的情况时会中止事务。这意味着可能的错误包括在事务中放入一些总是导致中止的东西,而不是你做了一些无法回滚的事情。


    您可能想尝试让编译器在没有函数调用的情况下发出三字节 XEND 指令,因此将返回地址压入堆栈不是事务的一部分。例如

    // no idea if this is safe, or if it might get reordered by the optimizer
    #define xend_MSVC  __asm _emit 0x0F  __asm _emit   0x01 __asm _emit 0xD5
    

    I think this does still work in 64bit mode,因为文档提到了rax,看起来IACA's header file 使用了__asm _emit

    我猜,将XEND 放在它自己的包装函数中会更安全。您只需要一个权宜之计,直到您可以升级到具有内在函数的编译器,因此只要来自 retcall 的额外读取/写入不会导致太多中止,它就不必是完美的.

    【讨论】:

      猜你喜欢
      • 2011-03-04
      • 2014-10-03
      • 1970-01-01
      • 1970-01-01
      • 2012-02-08
      • 2010-12-25
      • 1970-01-01
      • 2012-04-17
      • 2021-03-26
      相关资源
      最近更新 更多