我可以将 Thread Sanitizer 用于 OpenMP 程序吗?
Can I use Thread Sanitizer for OpenMP programs?
考虑以下示例:
#include <iostream>
int main () {
int i = 0;
#pragma omp parallel
{
#pragma omp critical
{
++i;
}
}
std::cout << i;
}
使用 g++ -fopenmp -fsanitize=thread
和 运行 编译得到
WARNING: ThreadSanitizer: data race (pid=9576)
Read of size 4 at 0x7ffdc170f600 by thread T1:
#0 main._omp_fn.0 (a.out+0x000000400d20)
#1 gomp_thread_start /build/gcc/src/gcc-5.2.0/libgomp/team.c:118 (libgomp.so.1+0x00000000f42d)
Previous write of size 4 at 0x7ffdc170f600 by thread T2:
#0 main._omp_fn.0 (a.out+0x000000400d35)
#1 gomp_thread_start /build/gcc/src/gcc-5.2.0/libgomp/team.c:118 (libgomp.so.1+0x00000000f42d)
Location is stack of main thread.
Thread T1 (tid=9578, running) created by main thread at:
#0 pthread_create /build/gcc/src/gcc-5.2.0/libsanitizer/tsan/tsan_interceptors.cc:895 (libtsan.so.0+0x000000027a37)
#1 gomp_team_start /build/gcc/src/gcc-5.2.0/libgomp/team.c:796 (libgomp.so.1+0x00000000f98f)
#2 __libc_start_main (libc.so.6+0x00000002060f)
Thread T2 (tid=9579, running) created by main thread at:
#0 pthread_create /build/gcc/src/gcc-5.2.0/libsanitizer/tsan/tsan_interceptors.cc:895 (libtsan.so.0+0x000000027a37)
#1 gomp_team_start /build/gcc/src/gcc-5.2.0/libgomp/team.c:796 (libgomp.so.1+0x00000000f98f)
#2 __libc_start_main (libc.so.6+0x00000002060f)
SUMMARY: ThreadSanitizer: data race ??:0 main._omp_fn.0
据我所知,这是误报。有没有办法避免这种情况?
(使用 clang 和 libomp 也可以。)
即使有抑制,您仍然会在 OpenMP 运行时得到误报,因为运行时中有一些 Tsan 无法理解的同步机制。
我们致力于 OpenMP 运行时,让 Tsan 理解这个同步点并消除所有误报。
看看这个项目:
https://github.com/PRUNER/archer
如果您需要更多帮助,请告诉我。
最佳,
西蒙
是的,至少对于 Clang,这相对容易。您需要构建具有 ThreadSanitizer 支持的 libomp(Clang 使用它而不是 libgomp)。这不会花那么长时间:
git clone https://github.com/llvm/llvm-project
cd llvm-project
mkdir build
cd build
cmake -DLIBOMP_TSAN_SUPPORT=1 ../openmp
sudo cmake --build . --target install
(sudo
和--target install
是可选的,如果你把路径调整到下面的libomp.so
)
现在 运行 如果您使用这个 libomp.so
而不是系统一个,您的示例可以正常工作:
clang++ -fsanitize=thread -fopenmp main.cpp
env LD_PRELOAD=/usr/local/lib/libomp.so ./a.out
考虑以下示例:
#include <iostream>
int main () {
int i = 0;
#pragma omp parallel
{
#pragma omp critical
{
++i;
}
}
std::cout << i;
}
使用 g++ -fopenmp -fsanitize=thread
和 运行 编译得到
WARNING: ThreadSanitizer: data race (pid=9576)
Read of size 4 at 0x7ffdc170f600 by thread T1:
#0 main._omp_fn.0 (a.out+0x000000400d20)
#1 gomp_thread_start /build/gcc/src/gcc-5.2.0/libgomp/team.c:118 (libgomp.so.1+0x00000000f42d)Previous write of size 4 at 0x7ffdc170f600 by thread T2:
#0 main._omp_fn.0 (a.out+0x000000400d35)
#1 gomp_thread_start /build/gcc/src/gcc-5.2.0/libgomp/team.c:118 (libgomp.so.1+0x00000000f42d)Location is stack of main thread.
Thread T1 (tid=9578, running) created by main thread at:
#0 pthread_create /build/gcc/src/gcc-5.2.0/libsanitizer/tsan/tsan_interceptors.cc:895 (libtsan.so.0+0x000000027a37)
#1 gomp_team_start /build/gcc/src/gcc-5.2.0/libgomp/team.c:796 (libgomp.so.1+0x00000000f98f)
#2 __libc_start_main (libc.so.6+0x00000002060f)Thread T2 (tid=9579, running) created by main thread at:
#0 pthread_create /build/gcc/src/gcc-5.2.0/libsanitizer/tsan/tsan_interceptors.cc:895 (libtsan.so.0+0x000000027a37)
#1 gomp_team_start /build/gcc/src/gcc-5.2.0/libgomp/team.c:796 (libgomp.so.1+0x00000000f98f)
#2 __libc_start_main (libc.so.6+0x00000002060f)SUMMARY: ThreadSanitizer: data race ??:0 main._omp_fn.0
据我所知,这是误报。有没有办法避免这种情况?
(使用 clang 和 libomp 也可以。)
即使有抑制,您仍然会在 OpenMP 运行时得到误报,因为运行时中有一些 Tsan 无法理解的同步机制。
我们致力于 OpenMP 运行时,让 Tsan 理解这个同步点并消除所有误报。
看看这个项目:
https://github.com/PRUNER/archer
如果您需要更多帮助,请告诉我。
最佳,
西蒙
是的,至少对于 Clang,这相对容易。您需要构建具有 ThreadSanitizer 支持的 libomp(Clang 使用它而不是 libgomp)。这不会花那么长时间:
git clone https://github.com/llvm/llvm-project
cd llvm-project
mkdir build
cd build
cmake -DLIBOMP_TSAN_SUPPORT=1 ../openmp
sudo cmake --build . --target install
(sudo
和--target install
是可选的,如果你把路径调整到下面的libomp.so
)
现在 运行 如果您使用这个 libomp.so
而不是系统一个,您的示例可以正常工作:
clang++ -fsanitize=thread -fopenmp main.cpp
env LD_PRELOAD=/usr/local/lib/libomp.so ./a.out