Zoeken…


Invoering

Dit onderwerp behandelt de basisprincipes van gelijktijdigheid in C ++ met OpenMP. OpenMP wordt gedetailleerder gedocumenteerd in de OpenMP-tag .

Parallellisme of gelijktijdigheid impliceert de uitvoering van code tegelijkertijd.

Opmerkingen

OpenMP vereist geen speciale headers of bibliotheken omdat het een ingebouwde compilerfunctie is. Als u echter OpenMP API-functies gebruikt, zoals omp_get_thread_num() , moet u omp.h en de bijbehorende bibliotheek opnemen.

OpenMP- pragma instructies worden genegeerd wanneer de OpenMP-optie niet is ingeschakeld tijdens het compileren. Misschien wilt u de compileroptie in de handleiding van uw compiler raadplegen.

  • GCC gebruikt -fopenmp
  • Clang gebruikt -fopenmp
  • MSVC gebruikt /openmp

OpenMP: Parallelle secties

Dit voorbeeld illustreert de basisprincipes van het parallel uitvoeren van secties code.

Omdat OpenMP een ingebouwde compilerfunctie is, werkt het op alle ondersteunde compilers zonder enige bibliotheken op te nemen. U kunt omp.h als u een van de openMP API-functies wilt gebruiken.

Voorbeeldcode

std::cout << "begin ";
//    This pragma statement hints the compiler that the
//    contents within the { } are to be executed in as
//    parallel sections using openMP, the compiler will
//    generate this chunk of code for parallel execution
#pragma omp parallel sections
{
    //    This pragma statement hints the compiler that
    //    this is a section that can be executed in parallel
    //    with other section, a single section will be executed
    //    by a single thread.
    //    Note that it is "section" as opposed to "sections" above
    #pragma omp section
    {
        std::cout << "hello " << std::endl;
        /** Do something **/
    }
    #pragma omp section
    {
        std::cout << "world " << std::endl;
        /** Do something **/
    }
}
//    This line will not be executed until all the
//    sections defined above terminates
std::cout << "end" << std::endl;

uitgangen

Dit voorbeeld produceert 2 mogelijke uitgangen en is afhankelijk van het besturingssysteem en de hardware. De output illustreert ook een race-conditieprobleem dat zou optreden bij een dergelijke implementatie.

UITGANG A UITGANG B
begin hallo wereld einde begin wereld hallo einde

OpenMP: Parallelle secties

Dit voorbeeld laat zien hoe brokken code parallel kunnen worden uitgevoerd

std::cout << "begin ";
//    Start of parallel sections
#pragma omp parallel sections
{
    //    Execute these sections in parallel
    #pragma omp section
    {
        ... do something ...
        std::cout << "hello ";
    }
    #pragma omp section
    {
        ... do something ...
        std::cout << "world ";
    }
    #pragma omp section
    {
        ... do something ...
        std::cout << "forever ";
    }
}
//    end of parallel sections
std::cout << "end";

uitgang

  • begin hallo wereld voor altijd einde
  • begin wereld hallo voor altijd einde
  • begin hallo voor altijd einde van de wereld
  • begin voor altijd hallo wereld einde

Aangezien de uitvoeringsvolgorde niet is gegarandeerd, kunt u een van de bovenstaande uitvoer waarnemen.

OpenMP: Parallel For Loop

Dit voorbeeld laat zien hoe een lus in gelijke delen kan worden verdeeld en parallel kan worden uitgevoerd.

//    Splits element vector into element.size() / Thread Qty
//    and allocate that range for each thread.
#pragma omp parallel for
for    (size_t i = 0; i < element.size(); ++i)
    element[i] = ...

//    Example Allocation (100 element per thread)
//    Thread 1 : 0 ~ 99
//    Thread 2 : 100 ~ 199
//    Thread 2 : 200 ~ 299
//    ...

//    Continue process
//    Only when all threads completed their allocated
//    loop job
...

* Let op dat u de grootte van de vector die parallel wordt gebruikt voor lussen niet wijzigt, omdat toegewezen bereikindexen niet automatisch worden bijgewerkt .

OpenMP: Parallel Gathering / Reduction

Dit voorbeeld illustreert een concept om reductie of verzameling uit te voeren met std::vector en OpenMP.

Stel dat we een scenario hebben waarin we meerdere threads willen gebruiken om een heleboel dingen te genereren, int wordt hier voor de eenvoud gebruikt en kan worden vervangen door andere gegevenstypen.

Dit is met name handig wanneer u resultaten van slaves moet samenvoegen om segmentfouten of geheugentoegangsschendingen te voorkomen en geen bibliotheken of aangepaste sync-containerbibliotheken wilt gebruiken.

//    The Master vector
//    We want a vector of results gathered from slave threads
std::vector<int> Master;    

//    Hint the compiler to parallelize this { } of code
//    with all available threads (usually the same as logical processor qty)
#pragma omp parallel
{
    //    In this area, you can write any code you want for each
    //    slave thread, in this case a vector to hold each of their results
    //    We don't have to worry about how many threads were spawn or if we need
    //    to repeat this declaration or not.
    std::vector<int> Slave;

    //    Tell the compiler to use all threads allocated for this parallel region
    //    to perform this loop in parts. Actual load appx = 1000000 / Thread Qty
    //    The nowait keyword tells the compiler that the slave threads don't
    //    have to wait for all other slaves to finish this for loop job
    #pragma omp for nowait
    for (size_t i = 0; i < 1000000; ++i
    {
        /* Do something */
        ....
        Slave.push_back(...);
    }

    //    Slaves that finished their part of the job
    //    will perform this thread by thread one at a time
    //    critical section ensures that only 0 or 1 thread performs
    //    the { } at any time
    #pragma omp critical
    {
        //    Merge slave into master
        //    use move iterators instead, avoid copy unless
        //    you want to use it for something else after this section
        Master.insert(Master.end(), 
                      std::make_move_iterator(Slave.begin()), 
                      std::make_move_iterator(Slave.end()));
    }
}

//    Have fun with Master vector
...


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow