2012-02-06 33 views
7

Hola tengo el siguiente código, que puedo compilar con gcc (> 4,2) con la bandera -fopenmp:comportamiento extraño OpenMP

int main(void) 
{ 
#pragma omp parallel for 
    int i; 
    for(i=0;i<4;i++) while(1); 

    return 0; 
} 

Puedo obtener un SIGSEGV en OSX Lion (versión 1.7.3, llvm-gcc 4.2.1) y CentOS 6.2. ¿Qué estoy haciendo mal aquí? Gracias

+0

Obtengo lo mismo, Win7/cygwin, gcc 4.5.0. Lo ejecuté a través de gdb: crea los hilos y luego recibo 'Program received signal SIGSEGV, Segmentation fault. 0x63602726 en omp_get_max_active_levels() '. Funciona bien sin el 'while (1)'. ¿Cómo trata OpenMP ese bucle infinito? –

+0

Estás usando una variable no declarada. Pero eso debería generar un error de compilación, no un segfault. Pero con 'i' declarado también recibo un segfault, gcc-4.5.1, openSuSE 11.4. –

+0

Olvidé agregar ... int i .. Escribí el código a toda prisa: D. – sfa

Respuesta

1

Hubo un error en el gcc con respecto a este problema, lo informé y proporcionarán una solución. Aquí está el enlace: GCC bug

1

Muy interesante.

he cambiado el código un poco por lo

int main(void) 
{ 
int i; 
#pragma omp parallel 
    { 
     while(1); 
    } 
    return 0; 
} 

y así

inline void func() { 
    while (1) ; 
} 

int main(void) 
{ 
int i; 
#pragma omp parallel for 
    for(i=0;i<8;i++) { 
     func(); 
    } 
    return 0; 
} 

Y ambos funcionaba bien.

+0

Lo sé, también probé esto último. (también funciona sin el en línea). Pero, ¿qué crees que está mal con el código que escribí, (excepto que falta un ... int i). En mi CentOS se llama a gomp_loop_static_start(), con parámetros como => chunk_size = 140737488347560, istart = 0x7fffffffe1b0, iend = 0xca. El último es un puntero que se desreferencia ... obteniendo el SIGSEGV. Si utilizo schedule() explícitamente para establecer el tamaño del fragmento a un valor, el puntero iend es una dirección válida ... y no obtengo SIG 11. También si depuro su último código (con el fnc en línea) gomp_loop_static_start() no lo hace ser llamado en absoluto. – sfa

+0

si compila con optimizaciones habilitadas, entonces también obtiene segfault para el caso 'func()'. – jfs

+0

@ J.F.Sebastian No aquí, con 'func()', no hace nada correctamente en 390 +% CPU, de -O0 a -O3 y -Os. Segfaults con un sin adornos 'while (1);' en todos los niveles de optimización. gcc es 4.5.1. Muy extraño. –

2

No estoy seguro si esto es relevante para la versión del compilador y configuración, pero while(true){} terminates

Más precisamente, si se escribe un bucle que

  • no realiza ninguna llamada a la biblioteca de funciones de I/O, y
  • no accede ni modifica los objetos volátiles, y
  • no realiza operaciones de sincronización (1.10) o atómicas (Cláusula 29)

y no termina, usted tiene comportamiento indefinido.

Esto puede terminar no aplicando a su situación, pero a medida que C++ 11 se vuelve más establecido, tenga cuidado.

+0

Irrelevante, esto es C, y en C, solo se puede suponer que el ciclo termina si la expresión de control ** no es una expresión constante **. Como 'while (1);' está controlado por una expresión constante, el ciclo no debe terminar. –

+0

Interesante, no me di cuenta que C tenía una calidad de expresión no constante como esa. ¿Puedes señalar el estándar, por favor? – spraff

+0

Hola spraff, no veo ningún comportamiento indefinido en C => mientras (1); (señale el estándar C por favor). Debería ser un salto incondicional (jmp) saltando en su propia dirección. Si creo 4 hilos (con pthread_create) y pongo en la función de inicio un "while (1);" No obtengo SIGSEGV, y mis 4 núcleos están al 100%. Quería lograr el mismo comportamiento con openmp, pero parece que no es tan confiable como pensaba. – sfa