Helgrind (Valgrind) 和 OpenMP (C):避免误报?
Posted
技术标签:
【中文标题】Helgrind (Valgrind) 和 OpenMP (C):避免误报?【英文标题】:Helgrind (Valgrind) and OpenMP (C): avoiding false positives? 【发布时间】:2012-05-25 09:34:25 【问题描述】:Valgrind 线程错误检测工具 Helgrind 的文档,找到 here
警告说,如果您使用 GCC 编译您的 OpenMP 代码,GCC 的 OpenMP 运行时库 (libgomp.so) 将导致数据争用的误报报告的混乱,因为它使用原子机器指令和 Linux futex 系统调用,而不是 POSIX pthreads 原语。它告诉您,您可以通过使用 --disable-linux-futex
配置选项重新编译 GCC 来解决此问题。
所以我尝试了这个。我使用 --disable-linux-futex
配置选项编译并安装到本地目录 (~/GCC_Valgrind/gcc_install) 新的 GCC 版本 4.7.0(撰写本文时的最新版本)。然后我创建了一个没有可见数据竞争的小型 OpenMP 测试程序 (test1.c):
/* test1.c */
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 2
int a[NUM_THREADS];
int main(void)
int i;
#pragma omp parallel num_threads(NUM_THREADS)
int tid = omp_get_thread_num();
a[tid] = tid + 1;
for (i = 0; i < NUM_THREADS; i++)
printf("%d ", a[i]);
printf("\n");
return EXIT_SUCCESS;
我将这个程序编译如下
~/GCC_Valgrind/gcc_install/bin/gcc -Wall -fopenmp -static -L~/GCC_Valgrind/gcc_install/lib64 -L~/GCC_Valgrind/gcc_install/lib -o test1 test1.c
但是,我收到了 30 份误报数据竞争报告!--全部发生在 libgomp 代码中。然后我编译了没有-static
标志的test1.c,然后再次运行Helgrind。这一次,我只收到了 9 个误报数据竞争报告,但这仍然太多了——而且,如果没有 -static
标志,我无法在 libgomp 代码中追踪假定的竞争。 p>
是否有人找到了一种方法来减少(如果不能消除)来自 Helgrind 的误报数据竞争报告的数量,该报告应用于使用 GCC 编译的 OpenMP 程序?谢谢!
【问题讨论】:
只是一个疯狂的猜测 - 可能是您重新编译的 gcc 链接到重新编译的 libgomp 版本,但动态链接器仍然加载提供的系统libgomp 在运行时?尝试使用-Wl,-rpath,/path/to/recompiled/lib
重新编译。
只是附注 - 在工具集仍然免费的情况下尝试使用 Oracle Solaris Studio for Linux 中的线程分析器工具 :)
您是否考虑过添加错误抑制? valgrind.org/docs/manual/manual-core.html#manual-core.suppress
只是为了确定,你能把tid
标记为私人吗?
@user1202136 你是怎么做到的?
【参考方案1】:
很抱歉把这个作为答案,因为它更像是一个评论,但它太长了,不适合作为评论,所以这里是:
来自您引用的网站。
GNU OpenMP(GCC 的一部分)的运行时支持库,至少对于 GCC 版本 4.2 和 4.3。 GNU OpenMP 运行时库 (libgomp.so) 使用以下组合构建自己的同步原语 原子内存指令和 futex 系统调用,这会导致总 Helgrind 的混乱,因为它无法“看到”那些。
幸运的是,这可以使用配置时选项来解决(对于 海湾合作委员会)。从源代码重建 GCC,并使用配置 --禁用-linux-futex。这使得 libgomp.so 改为使用标准的 POSIX 线程原语。请注意,这是使用 GCC 测试的 4.2.3 并且尚未使用更新的 GCC 版本重新测试。我们将不胜感激听到更多关于任何成功或失败的信息 最新版本。
正如您在帖子中提到的,这与 libgomp.so
有关,但这是一个共享对象,所以我看不出您如何传递 -static 标志并仍然使用该库。我是不是被误导了?
【讨论】:
【参考方案2】:使其工作的步骤:
-
使用
--disable-linux-futex
重新编译gcc(包括libgomp)
确保在编译程序时使用 futex free gcc。
确保系统在执行程序时会加载 futex free libgomp(该库通常位于GCC-OBJ-DIR/PLATFORM/libgomp/.libs
)。例如通过设置LD_LIBRARY_PATH
环境变量:
导出 LD_LIBRARY_PATH=~/gcc-4.8.1-nofutex/x86_64-unknown-linux-gnu/libgomp/.libs:
【讨论】:
【参考方案3】:还请注意,如果在代码中使用omp_set_lock
,则必须替换omp.h
路径,因为锁结构大小不同。见https://xrunhprof.wordpress.com/2018/08/27/tsan-with-openmp/
【讨论】:
以上是关于Helgrind (Valgrind) 和 OpenMP (C):避免误报?的主要内容,如果未能解决你的问题,请参考以下文章
死锁问题分析的利器——valgrind的DRD和Helgrind