Рассмотрим следующий пример:
#include <iostream>
int main () {
int i = 0;
#pragma omp parallel
{
#pragma omp critical
{
++i;
}
}
std::cout << i;
}
Компилирование с g++ -fopenmp -fsanitize=thread
и работает доходность
ВНИМАНИЕ: ThreadSanitizer: гонка данных (pid = 9576)
Считайте размер 4 в 0x7ffdc170f600 по теме 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)Предыдущая запись размера 4 в 0x7ffdc170f600 по теме 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)Расположение — стек основного потока.
Поток T1 (tid = 9578, работает), созданный основным потоком по адресу:
# 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)Поток T2 (tid = 9579, работает), созданный основным потоком в:
# 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)РЕЗЮМЕ: ThreadSanitizer: гонка данных ??: 0 main._omp_fn.0
Насколько я вижу, это ложный позитив. Есть ли способ избежать этого?
(Что-то, работающее с clang и libomp, тоже подойдет.)
даже при подавлении вы все равно будете получать ложные срабатывания во время выполнения OpenMP, потому что есть некоторый механизм синхронизации во время выполнения, который Цан не в состоянии понять.
Мы работали над средой выполнения OpenMP, чтобы Цан понимал эту точку синхронизации и удалял все ложные срабатывания.
Посмотрите на этот проект:
https://github.com/PRUNER/archer
Дай мне знать, если тебе еще понадобится помощь.
Лучший,
Симона
Других решений пока нет …