2012-02-06 3 views
7

Ciao Ho il seguente codice, che compilo con gcc (> 4.2) con la bandierina -fopenmp:strano comportamento OpenMP

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

    return 0; 
} 

ho ottenere un SIGSEGV su OSX Lion (versione 1.7.3, LLVM-GCC 4.2.1) e CentOS 6.2. Cosa sto facendo di sbagliato qui? Grazie

+0

Ho lo stesso, Win7/cygwin, gcc 4.5.0. L'ho eseguito anche se gdb: crea i thread e poi ricevo 'Program ricevuto segnale SIGSEGV, errore di segmentazione. 0x63602726 in omp_get_max_active_levels() '. Funziona bene senza il 'while (1)'. In che modo OpenMP tratta questo ciclo infinito? –

+0

Stai utilizzando una variabile non dichiarata. Ma questo dovrebbe generare un errore di compilazione, non un segfault. Ma con 'i' dichiarato che ho anche un segfault, gcc-4.5.1, openSuSE 11.4. –

+0

Ho dimenticato di aggiungere .. int i .. Ho scritto il codice in fretta: D. – sfa

risposta

1

Si è verificato un errore nella gcc in merito a questo problema, l'ho segnalato e forniranno una correzione. Ecco il link: GCC bug

1

Molto interessante.

ho cambiato il codice un po ' così

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

e così

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

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

E hanno entrambi lavorato su OK.

+0

Lo so, ho provato anche quest'ultimo. (Funziona anche senza la riga). Ma cosa pensi sia sbagliato con il codice che ho scritto, (eccetto che manca un ... int i). Sul mio CentOS gomp_loop_static_start() viene chiamato, con parametri come => chunk_size = 140737488347560, istart = 0x7fffffffe1b0, iend = 0xca. L'ultimo è un puntatore che ottiene il dereferenziato, ottenendo quindi SIGSEGV. Se uso esplicitamente schedule() per impostare la dimensione del chunk su un valore, il puntatore di iend è un indirizzo valido .. e non ottengo SIG 11. Inoltre, se eseguo il debug del tuo ultimo codice (con il fnc in linea) gomp_loop_static_start() non lo fa ottenere chiamato. – sfa

+0

se si compila con le ottimizzazioni abilitate, si ottiene anche il segfault per il caso 'func()'. – jfs

+0

@ J.F.Sebastian Non qui, con 'func()', non fa niente correttamente a 390 +% CPU, da -0 a -O3 e -Os. Segfaults con un disadattato 'while (1);' su tutti i livelli di ottimizzazione. gcc è 4.5.1. Molto strano. –

2

Non so se questo è rilevante per la versione del compilatore e la configurazione, ma while(true){} terminates

Più precisamente, se si scrive un ciclo che

  • fa nessuna chiamata mediante la libreria funzioni di I/O, e
  • non accede o modifica oggetti volatili e
  • non esegue operazioni di sincronizzazione (1.10) o operazioni atomiche (clausola 29)

e non termina, si ha comportamento non definito.

Questo potrebbe finire non si applica alla situazione, ma come C++ 11 diventa più consolidata, attenzione.

+0

Irrilevante, questo è C, e in C, si può supporre che il ciclo termini solo se l'espressione di controllo è ** non un'espressione costante **. Poiché 'while (1);' è controllato da un'espressione costante, il ciclo non deve terminare. –

+0

Interessante, non mi ero reso conto che C avesse una qualità di espressione non costante come quella. Puoi indicare lo standard, per favore? – spraff

+0

Ciao spraff, non vedo alcun comportamento indefinito in C => while (1); (puntare allo standard C per favore). Dovrebbe essere un salto incondizionato (jmp) che salta al suo indirizzo. Se creo 4 thread (con pthread_create) e inserisco la funzione di avvio a "while (1);" Non ricevo SIGSEGV e i miei 4 core sono al 100%. Volevo ottenere lo stesso comportamento con openmp, ma sembra che non sia così affidabile come pensavo. – sfa