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 代码中。然后我编译 test1.c 而没有-static
标志,并再次运行Helgrind。这次,我只获得了9个误报数据竞赛报告,但这仍然太多了 - 而且,如果没有-static
标志,我无法在 libgomp 代码中追踪所谓的竞赛。
有没有人找到一种方法来减少(如果不能消除)Helgrind应用于使用GCC编译的OpenMP程序的误报数据竞争报告的数量?谢谢!
答案 0 :(得分:2)
很抱歉把它作为一个答案,因为它更像是一个评论,但它太长了,不能作为评论,所以这里:
来自您引用的网站。
GNU OpenMP的运行时支持库(GCC的一部分),至少对于GCC而言 版本4.2和4.3。 GNU OpenMP运行时库(libgomp.so) 使用的组合构造自己的同步原语 原子内存指令和futex系统调用,导致总数 因为它无法“看到”那些在Helgrind以来的混乱。
幸运的是,这可以使用配置时选项解决(for GCC)。从源重建GCC,并使用配置 - 禁用Linux的futex的。这使得libgomp.so使用标准的POSIX线程原语。请注意,这是使用GCC测试的 4.2.3并未使用更新的GCC版本进行重新测试。我们希望听到更多的成功或失败 最新版本。
正如您在帖子中提到的,这与libgomp.so
有关,但这是一个共享对象,所以我看不出如何传递-static标志并仍然使用该库。我只是被误导了吗?
答案 1 :(得分:0)
使其有效的步骤:
--disable-linux-futex
GCC-OBJ-DIR/PLATFORM/libgomp/.libs
)。例如,通过设置LD_LIBRARY_PATH
环境变量:export LD_LIBRARY_PATH =〜/ gcc-4.8.1-nofutex / x86_64-unknown-linux-gnu / libgomp / .libs:
答案 2 :(得分:0)
还请注意,如果代码中使用omp_set_lock
,则由于锁结构大小不同,必须替换omp.h
路径。参见https://xrunhprof.wordpress.com/2018/08/27/tsan-with-openmp/