Helgrind(Valgrind) y OpenMP(C): ¿evitando falsos positivos?
race-condition false-positive (2)
La documentación para la herramienta de detección de errores de hilo Valgrind Helgrind, se encuentra here
advierte que, si usa GCC para compilar su código OpenMP, la biblioteca de tiempo de ejecución OpenMP ( libgomp.so ) causará un caos de informes positivos falsos de razas de datos, debido a su uso de instrucciones de máquina atómica y llamadas al sistema futex de Linux en lugar de POSIX pthreads primitivos. Sin embargo, le dice que puede resolver este problema recompilando GCC con la opción de configuración --disable-linux-futex
.
Así que probé esto. Recopilé e instalé en un directorio local ( ~ / GCC_Valgrind / gcc_install ) una nueva versión GCC 4.7.0 (la última versión al momento de escribir esto) con la opción de configuración --disable-linux-futex
. Luego creé un pequeño programa de prueba OpenMP ( test1.c ) que no tiene carreras de datos visibles:
/* 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;
}
Recopilé este programa de la siguiente manera
~/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
Sin embargo, obtuve 30 informes de raza de datos falsos positivos, todos ocurriendo en el código de libgomp . Luego compilé test1.c sin el distintivo -static y ejecuté Helgrind de nuevo. Esta vez, obtuve solo 9 informes de raza de datos positivos falsos, pero todavía son demasiados, y, sin la bandera -static
, no puedo rastrear la supuesta raza en el código libgomp .
¿Alguien ha encontrado una forma de reducir, si no eliminar, la cantidad de informes de raza de datos falsos positivos de Helgrind aplicados a un programa OpenMP compilado con GCC? ¡Gracias!
Pasos que lo harán funcionar:
- Recompile gcc (incluido libgomp) usando
--disable-linux-futex
- Asegúrese de utilizar el gcc libre de futex al compilar su programa.
- Asegúrese de que el sistema cargue la libgomp libre de futex al ejecutar su programa (la biblioteca generalmente se encuentra en
GCC-OBJ-DIR/PLATFORM/libgomp/.libs
). Por ejemplo, estableciendo laLD_LIBRARY_PATH
entornoLD_LIBRARY_PATH
:
exportar LD_LIBRARY_PATH = ~ / gcc-4.8.1-nofutex / x86_64-unknown-linux-gnu / libgomp / .libs:
Perdón por poner esto como una respuesta ya que es más un comentario, pero es demasiado largo para encajar como un comentario, así que aquí va:
Desde el sitio al que hizo referencia.
La biblioteca de soporte Runtime para GNU OpenMP (parte de GCC), al menos para las versiones 4.2 y 4.3 de GCC. La biblioteca de tiempo de ejecución GNU OpenMP (libgomp.so) construye sus propias primitivas de sincronización utilizando combinaciones de instrucciones de memoria atómica y fuxo syscall, lo que causa un caos total ya que en Helgrind no se pueden "ver".
Afortunadamente, esto se puede resolver usando una opción de tiempo de configuración (para GCC). Reconstruye GCC desde el origen y configúralo con --disable-linux-futex. Esto hace que libgomp.so use las primitivas de enhebrado POSIX estándar. Tenga en cuenta que esto se probó utilizando GCC 4.2.3 y no se ha vuelto a probar con versiones más recientes de GCC. Agradeceríamos escuchar acerca de cualquier éxito o falla con versiones más recientes.
como mencionaste en tu publicación, esto tiene que ver con libgomp.so
, pero ese es un objeto compartido, por lo que no veo cómo puedes pasar el indicador estático y seguir usando esa biblioteca. ¿Estoy mal informado?