2013-07-10 10 views
7

Sto creando un controllo numero primo di base, basato su C - determine if a number is prime, ma utilizzando OpenMP.Errore di compilazione "predicato di controllo non valido" con OpenMP

int isPrime(int value) 
{ 
    omp_set_num_threads(4); 

    #pragma omp parallel for 
    for(int j = 2; j * j <= value; j++) 
    { 
    if (value % j == 0) return 0; 
    } 
    return value; 
} 

Quando si compila con -fopenmp, GCC versione 4.7.2 è erroring, affermando invalid controlling predicate rispetto al ciclo for.

Sembra che questo errore sia causato dal j al quadrato nel ciclo for. C'è un modo per aggirare questo problema e ottenere comunque l'output desiderato dall'algoritmo?

+0

sei sicuro che l'istruzione return sia consentita in un costrutto di ciclo aperto di mp? – alexbuisson

+0

Sfortunatamente, parallelizzare il ciclo con OpenMP non aiuterà a testare un singolo primo con la divisione di prova. Tuttavia, è possibile utilizzarlo in modo efficace per testare più numeri primi utilizzando la divisione di prova. Tuttavia, per trovare liste di numeri primi, raccomando il Sieve di Eratostene. Ecco una versione che utilizza OpenMP http://create.stephan-brumme.com/eratosthenes/ –

+0

Inoltre, nella funzione 'isPrime' ti consiglio di usare' j <= j/value' invece di 'j * j <= value' che può overflow http://rosettacode.org/wiki/Primality_by_trial_division#C –

risposta

8

return non è consentito all'interno del ciclo in quanto causerà l'uscita prima delle parentesi graffe.

Nota la definizione riportata qui sotto:

Dal spec OpenMP V2.5, 1.2.2 OpenMP lingua la terminologia, p2: 17-

blocco strutturato - per C/C++, un'istruzione eseguibile , possibilmente composto , con una sola voce nella parte superiore e una singola uscita sul fondo .

Un blocco strutturato inizia con l'apertura { e termina con la chiusura }. Lo return è contenuto in queste parentesi, quindi questo programma viola anche la definizione OpenMP per un blocco strutturato, poiché ha due uscite (una allo return e una all'uscita attraverso la parentesi)

OpenMP pone le seguenti cinque restrizioni su quali loop possono essere infilati:

  • La variabile di ciclo deve essere di tipo intero con segno. Gli interi senza segno, come DWORD, non funzioneranno.
  • L'operazione di confronto deve essere in forma loop_variable <, <=, >, o >= loop_invariant_integer
  • La terza espressione o incremento porzione del ciclo for deve essere numeri interi aggiunta o intero sottrazione e da un anello invariante valore.
  • Se l'operazione di confronto è < o <=, l'indice del ciclo deve incremento su ogni iterazione, e viceversa, se l'operazione di confronto è > o >=, l'indice del ciclo deve diminuire su ogni iterazione.
  • Il ciclo deve essere un blocco di base, ovvero nessun salto dall'interno di il ciclo verso l'esterno sono consentiti ad eccezione dell'istruzione di uscita, che termina l'intera applicazione. Se si utilizzano le istruzioni goto o break, devono saltare all'interno del ciclo, non all'esterno di . Lo stesso vale per la gestione delle eccezioni; le eccezioni devono essere catturate all'interno del ciclo.
+0

Non capisco perché la variabile loop debba essere firmata. Cosa succede se hai bisogno di un numero maggiore di un numero a 8 byte con segno? – Nubcake

2

Secondo lo standard OpenMP (§ 2.5.1, p.40), le forme accettabili di predicato controllo del ciclo for sono:

  • var relazionale-op b e
  • b relazionale-op var

L'utilizzo j * j <= value è una chiara violazione di questo requisito. La logica è che richiede al compilatore di emettere il codice che calcola la radice quadrata intera di value in fase di esecuzione, con quest'ultimo indefinito per alcuni valori di value, in particolare per quelli negativi.

È possibile sostituire j * j <= value con j <= sqrt_value, dove sqrt_value è il numero intero radice quadrata di value, ma poi sarebbe arrivato il problema di avere un percorso di uscita alternativa nel blocco strutturato all'interno del ciclo. Sfortunatamente non esiste una soluzione facile in questo caso poiché OpenMP non supporta la terminazione prematura di loop paralleli.

Problemi correlati