Helgrind(Valgrind)和OpenMP(C):避免误报?

时间:2012-05-17 19:05:48

标签: c openmp valgrind race-condition false-positive

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程序的误报数据竞争报告的数量?谢谢!

3 个答案:

答案 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)

使其有效的步骤:

  1. 使用--disable-linux-futex
  2. 重新编译gcc(包括libgomp)
  3. 确保在编译程序时使用futex free gcc。
  4. 确保系统在执行程序时加载futex free libgomp(库通常位于GCC-OBJ-DIR/PLATFORM/libgomp/.libs)。例如,通过设置LD_LIBRARY_PATH环境变量:
  5.   

    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/