我想利用 Intel TSX 编写无锁代码。
xbegin
my_inst1
my_inst2
xend
但是,由于某些原因,我在 TSX 执行 TSX 中的一条指令中止。
我想知道哪条指令产生了故障并使 TSX 中止。
有没有办法知道哪条指令产生了错误?
我的第一次尝试是在 TSX 区域中执行每条指令后递增全局计数器。但是,当故障发生时,对计数器的更新也会回滚,因为它会回滚 TSX 区域中的每次写入。
调试 TSX 执行有什么技巧吗?
使用perf record
(或访问硬件性能计数器的其他方式)rtm_retired.aborted
用于任何中止等事件,和/或tx_mem.abort_conflict
查看tx_mem.abort_capacity
其中任何一个是否是中止的原因。(您可以在一次运行中记录多个事件,然后查看触发的事件perf report
)
tx_exec.misc1..3 也可能是相关的。在perf list
我的 Skylake 桌面上。
tx_exec.misc1
[计算可能导致事务中止的一类指令被执行的次数。由于这是执行计数,它可能并不总是导致事务中止]
tx_exec.misc2
[计算可能导致事务中止的一类指令(例如,vzeroupper)在事务区域内执行的次数]
tx_exec.misc3
[计算指令执行导致超出支持的事务嵌套计数的次数]
另请参阅https://oprofile.sourceforge.io/docs/intel-skylake-events.php
您可能需要调整一些东西以获得合理数量的样本,用于不经常触发的事件。我还没有尝试过,但希望计数应该显示在有罪指令本身上。 rtm_retired.aborted
是一个精确的事件;perf list
其他人在输出中没有这么说。
lock
一些 RTM/TSX 事件仅适用于 HLE(硬件锁定省略,您在ed 指令上放置一个额外的前缀)。
在输出中使用perf list
并搜索“abort”以查找相关事件。