中止的xbegin事务是否还原xbegin启动时存在的堆栈上下文
Does an aborted xbegin transaction restore the stack context that existed at the xbegin start?
我感兴趣的是将事务性xbegin和xend封装在静态汇编程序库中的xbegin()和xend()函数中。然而,我不清楚堆栈是如何(或是否)恢复到原始的xbegin调用状态的,因为xabort源自其他堆栈级别(更高或更低)。换句话说,动态堆栈上下文(包括中断效果)是否只是作为事务的另一部分进行管理和回滚?
此汇编程序方法对于不支持或不可用_xbegin()和_xend()内部函数的VC++2010生成是必需的,并且x64生成不能使用_asm{}内联。
相关:另请参阅David Kanter的TSX文章,了解它如何在引擎盖下工作以及软件如何从中受益的一些理论,以及这篇博客文章,了解HSW上的一些实验性能数据(在TSX错误被发现和微代码更新禁用该硬件上的TSX之前)。
xbegin
的Intel insn-ref手动输入非常清楚。(有关英特尔官方PDF和其他内容的链接,请参阅x86标签wiki。)
在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
的回退地址。
当然,您可能想做一些事情,而不是无限次重试中止。这并不是一个真正的例子。(这篇文章确实有一个你可能想使用的逻辑的真实例子,使用内部函数。看起来他们只是测试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
我认为这在64位模式下仍然有效,因为文档提到了rax
,而且IACA的头文件似乎使用了__asm _emit
。
我想,把XEND
放在自己的包装函数中也会更安全。在升级到具有内部函数的编译器之前,您只需要一个权宜之计,所以只要ret
和call
的额外读/写不会导致太多中止,它就不必是完美的。
- C++模板来检查友元函数的存在
- 既然存在危险,为什么项目要使用-I include开关
- 我们可以访问一个不存在的联盟的成员吗
- C++:对不存在的命名空间使用命名空间指令
- C++quit()函数中可能存在作用域问题
- C++擦除(如果存在)
- g++ 说函数不存在,即使包含正确的标头
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 有了gcc,是否可以链接库,但前提是它存在
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- C++Builder中的OnClick事件签名存在问题
- 如何正确地将分支添加到已存在的树中
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 如何检查QList中是否存在值
- 根据某个函数是否存在启用模板
- 如何将分支添加到已存在的TTree:ROOT
- 地图计数确实很重要,或者只是检查是否存在
- 通用C++/Python 多语言的存在
- 中止的xbegin事务是否还原xbegin启动时存在的堆栈上下文