中止的xbegin事务是否可以恢复xbegin开始时存在的堆栈上下文? [英] Does an aborted xbegin transaction restore the stack context that existed at the xbegin start?

查看:133
本文介绍了中止的xbegin事务是否可以恢复xbegin开始时存在的堆栈上下文?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有兴趣在XBEGIN()和XEND()函数中封装事务xbegin和xend到静态汇编库中。但是我不清楚给定一个来自其他堆栈级别(更高或更低)的xabort,如何将堆栈(或是否)还原到原始xbegin调用状态。换句话说,动态堆栈上下文(包括中断影响)是否作为事务的另一部分进行管理和回滚?

I am interested in encapsulating a transactional xbegin and xend inside XBEGIN( ) and XEND( ) functions, in a static assembler lib. However I am unclear how (or if) the stack gets restored to the original xbegin calling state, given an xabort originating at some other stack level (higher or lower). In other words, is the dynamic stack context (including interrupts effects) managed and rolled back as just another part of the transaction?

VC ++ 2010需要这种汇编器方法没有_xbegin()和_xend()内部函数受支持或不可用的内部版本,并且x64内部版本不能使用_asm {}内联。

This assembler approach is needed for a VC++ 2010 build that doesn't have _xbegin( ) and _xend( ) intrinsics supported or available, and x64 builds cannot use _asm { } inlining.

推荐答案

相关:另请参阅大卫·坎特(David Kanter)的TSX文章,以了解有关其如何在引擎盖以及软件如何从中受益,以及此博客文章获取HSW上的一些实验性能数据(在发现TSX错误并在该硬件上禁用微代码更新之前。)

related: See also David Kanter's TSX writeup for some theory on how it works under the hood and how software can benefit from it, and this blog post for some experimental performance numbers on HSW (before the TSX bug was discovered and microcode updates disabled TSX on that hardware.)

Intel insn参考手册请输入 xbegin 很清楚。 (有关指向英特尔官方的链接,请参见 x86 标签Wiki的问题) PDF和其他内容。)

The Intel insn ref manual entry for xbegin is pretty clear. (See the x86 tag wiki for links to Intel's official PDF, and other stuff.)


在RTM中止时,逻辑处理器丢弃所有体系结构
寄存器和内存在RTM执行期间执行的更新

将体系结构状态恢复到最外层的
XBEGIN指令所对应的状态。

On an RTM abort, the logical processor discards all architectural register and memory updates performed during the RTM execution and restores architectural state to that corresponding to the outermost XBEGIN instruction. The fallback address following an abort is computed from the outermost XBEGIN instruction.

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

So the instruction works like a conditional branch, where the branch condition is "did an abort happen before XEND?" e.g.:

; 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 的后备地址。

If an abort happens, it's as if all the code that ran after xbegin didn't run at all, just a jump to the fallback address with eax modified.

您可能想要当然,除了在终止操作上进行无限次重试外,还可以执行其他操作。这并不是一个真实的例子。 (本文确实有一个使用内在函数可能需要使用的那种逻辑。看起来它们只是测试 eax 而不是使用 xbegin 作为 if 的跳转,除非编译器优化了该检查。IDK是否是最有效的方法。)

You might want to do something other than just infinite retries on an abort, of course. This isn't meant to be a real example. (This article does have a real example of the kind of logic you might want to use, using intrinsics. It looks like they just test eax instead of using the xbegin as the jump in an if, unless the compiler optimizes that check. IDK if it's the most efficient way.)

什么是干扰效应?在当前的实现中,任何更改特权级别的操作(例如syscall或中断)都会导致事务中止。因此,环级更改永远不需要回滚。 CPU在遇到无法回滚的任何事情时只会中止事务。这意味着可能的错误包括在事务中放入某些东西总是会导致中止,但不是您做了一些无法回滚的事情。

What do you mean "interrupts effects"? In current implementations, anything that changes privilege level (like a syscall or interrupt) causes a transaction abort. So ring-level changes never need to be rolled back. The CPU will just abort the transaction when it encounters anything it can't roll back. This means the possible bugs include putting something inside the transaction that always causes an abort, but not that you do something that can't be rolled back.

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

You might want to try to get the compiler to emit the three-byte XEND instruction without a function call, so pushing the return address onto the stack isn't part of the transaction. e.g.

// 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

I think this does still work in 64bit mode, since the doc mentions rax, and it looks like IACA's header file uses __asm _emit.

XEND 。您只需要一个权宜之计,直到可以升级到具有内在函数的编译器,因此只要 ret 进行额外的读/写操作,它就不一定是完美的。和呼叫不会导致太多中止。

It'll be safer to put XEND in its own wrapper function, too, I guess. You just need a stop-gap until you can upgrade to a compiler with intrinsics, so it doesn't have to be perfect as long as the extra reads/writes from the ret and call don't cause too many aborts.

这篇关于中止的xbegin事务是否可以恢复xbegin开始时存在的堆栈上下文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆