当线程可能切换内核时如何正确使用 TSX-NI(HLE 和 RTM)?

How to properly use TSX-NI (both HLE and RTM) when threads might switch cores?

英特尔的事务同步扩展 (TSX-NI) 似乎在每个 CPU 的基础上工作。

这适用于 _InterlockedXxx_HLE{Acquire,Release} 硬件锁省略功能 (HLE),以及 _xbegin/_xend/等。受限事务内存 (RTM) 函数。

在多核系统上使用这些函数的"proper"方法是什么?

鉴于他们的正确性保证,我想我只需要担心这里的性能。

那么,考虑到线程总是有可能突然切换内核,因此这些指令可能需要回退到较慢的代码路径,因此我应该如何构建和编写代码以使我的代码具有最佳性能?

例如,我应该尝试明确设置线程 CPU 关联性,还是这种做法不好?
还有什么我应该担心的事情吗?

如果CPU中间有一个中断,事务将中止。在RIP保存之前处理中止,所以一个中断->CPU 迁移无法在这个或另一个核心上恢复,并且 运行 xend 不在事务内。

因此不存在正确性问题。


如果 OS 的进程调度程序会试图以对您的工作负载而言次优的方式来回跳转线程,则出于缓存局部性的原因,将线程固定到核心可以帮助提高性能。

但这对 TSX 没有特别的帮助:在中断后在同一核心上恢复也好不到哪里去,因为事务已经中止。 那个核心 拥有您需要的所有缓存行可能在 L1d 中仍然很热,并且希望仍处于独占或修改状态。


CPU 迁移只能发生在 user-space 任务上,当中断使它们进入睡眠状态,并且另一个内核上的内核决定获取该任务时。

在内核代码中,显然不要在事务中调用schedule();这对正确性并不重要,因为事务中止(可能)或最终或快速执行 returns 到此任务,我们达到 xend 并成功提交作为单个大事务发生的所有事情(包括所有内容调度程序和可能的另一个任务)。


我实际上并没有尝试过这个,但是我认为没有任何理由认为 TSX 的线程亲和性能考虑因素与非 TSX 有显着不同。