2010-09-23 25 views
19

OpenMP supporta nativamente la riduzione di una variabile che rappresenta una matrice?È possibile eseguire una riduzione su un array con openmp?

questo dovrebbe funzionare qualcosa di simile al seguente ...

float* a = (float*) calloc(4*sizeof(float)); 
omp_set_num_threads(13); 
#pragma omp parallel reduction(+:a) 
for(i=0;i<4;i++){ 
    a[i] += 1; // Thread-local copy of a incremented by something interesting 
} 
// a now contains [13 13 13 13] 

Idealmente, ci sarebbe qualcosa di simile per un OMP parallelo per, e se si dispone di un numero sufficiente di thread per poter dare un senso, l'accumulo avverrebbe tramite un albero binario.

+7

solo in FORTRAN – Anycorn

+1

può essere che si potrebbe spiegare un po 'di più ciò che si vuole fare esattamente. Fornire il codice seriale potrebbe aiutare. – FFox

+0

Scavando attorno a un po 'di più, suona come "solo in FORTRAN" è la risposta.Ho finito per allocare solo una vasta serie di copie locali al di fuori del ciclo, lasciando che i thread si accumulassero alle loro copie all'interno del ciclo for, quindi accumulando in un array globale dopo il ciclo for, ancora all'interno della regione parallela, all'interno di un sezione critica. –

risposta

3

Solo in Fortran in OpenMP 3.0, e, probabilmente, solo con alcuni compilatori.

Vedere l'ultimo esempio (Esempio 3) su:

http://wikis.sun.com/display/openmp/Fortran+Allocatable+Arrays

+3

Ora è possibile da OpenMP 4.5; vedere la risposta di Chen Jiang qui sotto. Fondamentalmente, è necessario specificare _array sections_ (consultare la sezione 2.4, pag.44 delle specifiche di OpenMP 4.5). La tua specifica #pragma sarà simile a questa: '#pragma omp riduzione parallela (+: a [: 4])' Attenzione, tuttavia, è necessario rendersi conto che ogni thread assegnerà la propria versione del sezione dell'array; se lo fai su grandi array con molti thread, potresti far esplodere la tua memoria. –

1

OpenMP non può eseguire riduzioni variabili matrice o struttura di tipo (vedi restrictions).

Si potrebbe anche voler leggere su private e shared clausole. private dichiara una variabile da privato a ogni filo, dove come shared dichiara una variabile da condividere tra tutti i thread. Ho anche trovato la risposta a questo question molto utile per quanto riguarda OpenMP e matrici.

3

riduzione Array è ora possibile con OpenMP 4.5 per C e C++. Ecco un esempio:

#include <iostream> 

int main() 
{ 

    int myArray[6] = {}; 

    #pragma omp parallel for reduction(+:myArray[:6]) 
    for (int i=0; i<50; ++i) 
    { 
    double a = 2.0; // Or something non-trivial justifying the parallelism... 
    for (int n = 0; n<6; ++n) 
    { 
     myArray[n] += a; 
    } 
    } 
    // Print the array elements to see them summed 
    for (int n = 0; n<6; ++n) 
    { 
    std::cout << myArray[n] << " " << std::endl; 
    } 
} 

Uscite:

100 
100 
100 
100 
100 
100 

ho compilato questo con GCC 6.2. Si può vedere quali versioni comuni del compilatore supportano le caratteristiche OpenMP 4.5 qui: http://www.openmp.org/resources/openmp-compilers/

nota dai commenti di cui sopra che, mentre questo è la sintassi conveniente, può invocare un sacco di spese generali di creare copie di ciascuna sezione array per ogni thread.

0

OpenMP può eseguire questa operazione di OpenMP 4.5 e GCC 6.3 (e possibilmente inferiore) sostiene. Un programma di esempio si presenta come segue:

#include <vector> 
#include <iostream> 

int main(){ 
    std::vector<int> vec; 

    #pragma omp declare reduction (merge : std::vector<int> : omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end())) 

    #pragma omp parallel for default(none) schedule(static) reduction(merge: vec) 
    for(int i=0;i<100;i++) 
    vec.push_back(i); 

    for(const auto x: vec) 
    std::cout<<x<<"\n"; 

    return 0; 
} 

noti che omp_out e omp_in sono variabili speciali e che il tipo di declare reduction deve corrispondere al vettore si sta progettando di ridurre il.