Sök…


parametrar

Klausul Parameter
private Kommaseparerad lista över privata variabler
firstprivate Som private , men initialiserat till värdet på variabeln innan du går in i slingan
lastprivate Som private , men variabeln får värdet som motsvarar den sista iterationen av slingan vid utgången
reduction reduktionsoperatör : kommaseparerad lista över motsvarande reduktionsvariabler
schedule static , dynamic , guided , auto eller runtime med valfri storleksstorlek efter koma för de 3 tidigare
collapse Antal perfekt kapslade öglor för att kollapsa och parallellisera tillsammans
ordered Berättar att vissa delar av slingan måste hållas i ordning (dessa delar identifieras specifikt med vissa ordered klausuler inuti slingkroppen)
nowait Ta bort den implicita barriären som finns i slutet av slingkonstruktionen

Anmärkningar

Betydelsen av schedule är följande:

  • static[,chunk] : Fördela statiskt (vilket innebär att fördelningen görs före inträdet i slinga) sling iterationer i satsvis av chunk storlek i en round-robin-sätt. Om chunk inte anges, då bitar är så jämn som möjligt och varje tråd får högst en av dem.
  • dynamic[,chunk] : Fördela sling iterationer bland trådarna genom satser av chunk storlek med en först till kvarn-först mala ordning, tills inga sats lämningar. Om det inte anges är chunk inställd på 1
  • guided[,chunk] : Som dynamic men med partier vilka storlekar blir mindre och mindre, ner till 1
  • auto : Låt kompilatorn och / eller körtidsbiblioteket bestämma vad som passar bäst
  • runtime : Avlägsna beslutet vid körning med hjälp av OMP_SCHEDULE miljövariabeln. Om miljövariabeln inte är definierad vid körtid kommer standard schemaläggning att användas

Standard för schedule är implementeringsdefiniera . I många miljöer är den static , men kan också vara dynamic eller mycket väl kunna vara auto . Var därför försiktig så att din implementering inte implicit förlitar sig på den utan att uttryckligen ställa in den.

I ovanstående exempel använde vi den smälta formen parallel for eller parallel do . Men slingkonstruktionen kan användas utan att smälta den med parallel , i form av ett #pragma omp for [...] eller !$omp do [...] fristående direktiv inom ett parallel område.

Endast för Fortran-versionen är loopindexvariabeln (-erna) för den / de parallella slingan (er) alltid private standard. Det finns därför inget behov av att uttryckligen förklara dem private (även om det inte är något fel).
För C- och C ++ -versionen är loopindexen precis som alla andra variabler. Därför, om deras räckvidd sträcker sig utanför de / de parallella slingorna (vilket betyder att de inte deklareras som for ( int i = ...) utan snarare som int i; ... for ( i = ... ) måste förklaras private .

Typiska exempel i C

#include <stdio.h>
#include <math.h>
#include <omp.h>

#define N 1000000

int main() {
    double sum = 0;

    double tbegin = omp_get_wtime();
    #pragma omp parallel for reduction( +: sum )
    for ( int i = 0; i < N; i++ ) {
        sum += cos( i );
    }
    double wtime = omp_get_wtime() - tbegin;

    printf( "Computing %d cosines and summing them with %d threads took %fs\n",
            N, omp_get_max_threads(), wtime );

    return sum;
}

I det här exemplet beräknar vi bara 1 miljon kosinus och summerar deras värden parallellt. Vi tar också tid på utförandet för att se om parallelliseringen har någon effekt på prestandan. Slutligen, eftersom vi mäter tiden måste vi se till att kompilatorn inte optimerar bort det arbete vi gjort, så vi låtsas använda resultatet genom att bara returnera det.

Samma exempel i Fortran

program typical_loop
    use omp_lib
    implicit none
    integer, parameter :: N = 1000000, kd = kind( 1.d0 )
    real( kind = kd ) :: sum, tbegin, wtime
    integer :: i

    sum = 0

    tbegin = omp_get_wtime()
    !$omp parallel do reduction( +: sum )
    do i = 1, N
        sum = sum + cos( 1.d0 * i )
    end do
    !$omp end parallel do
    wtime = omp_get_wtime() - tbegin

    print "( 'Computing ', i7, ' cosines and summing them with ', i2, &
        & ' threads took ', f6.4,'s' )", N, omp_get_max_threads(), wtime

    if ( sum > N ) then
        print *, "we only pretend using sum"
    end if
end program typical_loop

Även här beräknar vi och samlar en miljon kosinus. Vi tid på slingan och för att undvika oönskad kompilatoroptimering bort, låtsas vi använda resultatet.

Samla och köra exemplen

På en 8-kärnors Linux-maskin med GCC version 4.4 kan C-koderna sammanställas och köras på följande sätt:

$ gcc -std=c99 -O3 -fopenmp loop.c -o loopc -lm
$ OMP_NUM_THREADS=1 ./loopc
Computing 1000000 cosines and summing them with 1 threads took 0.095832s
$ OMP_NUM_THREADS=2 ./loopc
Computing 1000000 cosines and summing them with 2 threads took 0.047637s
$ OMP_NUM_THREADS=4 ./loopc
Computing 1000000 cosines and summing them with 4 threads took 0.024498s
$ OMP_NUM_THREADS=8 ./loopc
Computing 1000000 cosines and summing them with 8 threads took 0.011785s

För Fortran-versionen ger den:

$ gfortran -O3 -fopenmp loop.f90 -o loopf
$ OMP_NUM_THREADS=1 ./loopf
Computing 1000000 cosines and summing them with  1 threads took 0.0915s
$ OMP_NUM_THREADS=2 ./loopf
Computing 1000000 cosines and summing them with  2 threads took 0.0472s
$ OMP_NUM_THREADS=4 ./loopf
Computing 1000000 cosines and summing them with  4 threads took 0.0236s
$ OMP_NUM_THREADS=8 ./loopf
Computing 1000000 cosines and summing them with  8 threads took 0.0118s

Tillsats av två vektorer med hjälp av OpenMP parallellt för konstruktion

void parallelAddition (unsigned N, const double *A, const double *B, double *C)
{
    unsigned i;

    #pragma omp parallel for shared (A,B,C,N) private(i) schedule(static)
    for (i = 0; i < N; ++i)
    {
        C[i] = A[i] + B[i];
    }
}

Detta exempel lägger till två vektor ( A och B i C ) genom att leka ett team av trådar (specificerat av OMP_NUM_THREADS miljövariabel, till exempel) och tilldela varje tråd en bit av arbete (i det här exemplet, tilldelat statiskt genom schedule(static) uttryck).

Se kommentaravsnittet med avseende på den private(i) optionen.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow