我正在使用glibc 2.24版本。它具有通过事务同步扩展(例如_xbegin()和_xend())用于pthread_mutex_lock实现的锁定省略路径。我认为硬件应该支持锁定删除,因为hle CPU标志用于硬件锁定删除。我使用的处理器是采用Skylake架构的Intel®Xeon®Gold 6130。

首先,我想禁用Lock Elision,但是当我运行使用 perf stat -T 来监视事务周期的使用 pthread_mutex_lock 的程序时,我得到0。我认为这意味着pthread_mutex_lock根本不使用事务路径。谷歌搜索之后,我发现可能有必要首先使用 export GLIBC_TUNABLES = glibc.elision.enable = 1 来启用锁定清除,但是在此步骤之后,我仍然看不到任何使用perf的事务。

另一方面,当我包含_xbegin()时;和_xend();直接在此过程中,我获得了一些具有perf stat -T的交易周期,这应该意味着我希望在perf stat上寻找合适的计数器。

因此,有关如何启用锁定清除的任何建议都将有所帮助。还是我检查不正确?

更新TSX的我在主要功能中使用了这两条指令,就像这样:

_xbegin();
_xend();

我不确定它需要哪个库,我已经包含了其中的几十个。对于编译,我使用以下标志:-O3 -march = native -lpthread与该示例相关。

对于锁,我有互斥锁:
pthread_mutex_t * mutex;
mutex = (pthread_mutex_t *) malloc(10 * sizeof(pthread_mutex_t));
for(int k=0; k<10; k++){
    pthread_mutex_init(&mutex[k], NULL);
  }

也许为了省略,我应该以不同的方式初始化它?

最佳答案

在2.27之前的glibc早期版本中,只能使用称为enable-lock-elision的编译时标志来控制对TSX的支持。我不知道哪些版本启用或禁用了enable-lock-elision,但这就是它过去的工作方式1。因此,如果您想启用/指定TSX,则必须自己编译glibc并相应地使用该标志。从glibc 2.27开始,该编译时选项已删除,并由名为glibc.elision.enable的运行时选项代替。也就是说,glibc始终在支持TSX的情况下进行编译,但是只有在运行应用程序之前(例如,通过执行glibc.elision.enable)将环境变量export GLIBC_TUNABLES=glibc.elision.enable=1设置为1时,才使用TSX。

在2.27之前,glibc.elision.enable不存在,因此无效。是否使用TSX取决于编译时标志enable-lock-elision。您正在使用2.24。因此,最简单的解决方案是将其升级到2.27或更高版本。

请注意,根据相应的规范更新,当前所有支持TSX的Intel处理器似乎都具有与“使用Intel TSX指令可能导致不可预测的系统行为”相同的错误。对于某些处理器,英特尔已经发布了微代码更新,以实际禁用TSX。但是,将继续启用处理器上的实现。

脚注:

(1)根据此bug report,已从2.23开始禁用glibc中的锁省略。我认为这是通过在构建glibc时禁用enable-lock-elision来完成的,但是我没有通过查看代码来验证这一点。但这与您在2.24中被禁用的观察结果一致。

10-05 20:54
查看更多