c - 启用/禁用硬件锁定消除
问题描述
我正在使用 glibc 2.24 版本。它包含用于 pthread_mutex_lock 实现的锁省略路径,并带有事务同步扩展,例如 _xbegin() 和 _xend()。硬件应该支持锁定省略,因为我认为hle CPU 标志用于硬件锁定省略。我使用的处理器是带有 Skylake 架构的 Intel(R) Xeon(R) Gold 6130。
首先,我想禁用锁定省略,但是当我运行使用pthread_mutex_lock的程序时,使用perf stat -T来监视事务周期,我得到了 0。我认为这意味着 pthread_mutex_lock 根本不使用事务路径。谷歌搜索后,我发现可能需要先使用export GLIBC_TUNABLES=glibc.elision.enable=1来启用锁定省略,但在这一步之后,我仍然看不到任何带有 perf 的事务。
另一方面,当我包含 _xbegin(); 和 _xend(); 直接在此过程中,我使用 perf stat -T 获得了一些事务周期,这应该意味着我正在寻找具有 perf 的正确计数器,希望如此。
因此,任何关于如何启用锁定省略的建议都会有所帮助。还是我检查不正确?
TSX 的更新我在 main 函数中使用这两个指令,就像这样:
_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);
}
也许为了省略我应该以不同的方式初始化它?
解决方案
在 glibc 2.27 之前的早期版本中,只能使用名为enable-lock-elision
. 我不知道哪些版本已enable-lock-elision
启用或禁用,但这就是它过去的工作方式1。因此,如果您想启用/dsiable TSX,您必须自己编译 glibc 并相应地使用该标志。从glibc 2.27开始,该编译时选项被删除并被一个名为glibc.elision.enable
. 也就是说,glibc 总是在支持 TSX 的情况下编译,但只有glibc.elision.enable
在运行应用程序之前将环境变量设置为 1 时才会使用 TSX(例如,通过执行export GLIBC_TUNABLES=glibc.elision.enable=1
)。
2.27之前,glibc.elision.enable
不存在,所以没有效果。是否使用 TSX 取决于编译时标志enable-lock-elision
。您使用的是 2.24。所以最简单的解决方案是迁移到 2.27 或更新的版本。
请注意,当前所有支持 TSX 的 Intel 处理器似乎都存在相同的错误,即根据各自的规范更新,“使用 Intel TSX 指令可能导致不可预测的系统行为”。对于某些处理器,英特尔已发布微码更新以实际禁用 TSX。但是,您的处理器上的实现将继续启用。
脚注:
(1) 根据这个错误报告,从 2.23 开始,glibc 中的锁省略已被禁用。我认为这是通过enable-lock-elision
在构建 glibc 时禁用来完成的,但我没有通过查看代码来验证这一点。但这与您观察到它在 2.24 中被禁用是一致的。
推荐阅读
- javascript - 如何重定向到在 javascript 中添加收件人的 Outlook 邮件?
- xamarin - 在 Xamarin Forms iOS 中启用 AppCenter 崩溃和分析时,本机链接失败,重复符号:“_cxa+throw”
- jquery - 而不是正确的值 html 代码出现在 JQuery 中
- jquery - 如何在 CSS/jQuery 中强制 div 仅在一个方向上展开或调整大小
- javascript - 如何使用 Selenium WebDriver 检查元素是否在视图中?
- asp.net - 从 ASP.NET Core 2.2 迁移到 3.1 时 services.BuildServiceProvider(在 ConfigureServices 中)的替代代码
- python-3.x - 如果结果为空,则两个列表和处理异常之间的区别
- javascript - 为什么我的嵌套数组元素没有正确添加在一起?
- android - 如何在没有活动 android 的服务中修复 WindowManagerBadtokenException?
- c++ - 诠释 &b = ++a; // 这行工作正常 int &c = a++; //导致错误