Suche…


Einführung

Dieses Thema behandelt die Grundlagen der Parallelität in C ++ mit OpenMP. OpenMP ist im OpenMP-Tag ausführlicher dokumentiert.

Parallelität oder Parallelität impliziert die gleichzeitige Ausführung von Code.

Bemerkungen

OpenMP erfordert keine speziellen Header oder Bibliotheken, da es sich um eine integrierte Compiler-Funktion handelt. Wenn Sie jedoch OpenMP-API-Funktionen wie omp_get_thread_num() , müssen Sie omp.h und seine Bibliothek omp.h .

OpenMP- pragma Anweisungen werden ignoriert, wenn die OpenMP-Option während der Kompilierung nicht aktiviert ist. Sie können auf die Compiler-Option im Handbuch Ihres Compilers verweisen.

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

OpenMP: Parallele Abschnitte

Dieses Beispiel veranschaulicht die Grundlagen für die parallele Ausführung von Codeabschnitten.

Da OpenMP eine integrierte Compiler-Funktion ist, kann es auf jedem unterstützten Compiler ohne Bibliotheken verwendet werden. Sie können omp.h wenn Sie die openMP-API-Funktionen verwenden möchten.

Beispielcode

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;

Ausgänge

Dieses Beispiel liefert 2 mögliche Ausgänge und ist abhängig von Betriebssystem und Hardware. Die Ausgabe zeigt auch ein Race-Condition- Problem, das bei einer solchen Implementierung auftreten würde.

AUSGABE A AUSGABE B
begin hallo welt ende Welt beginnen Hallo Ende

OpenMP: Parallele Abschnitte

Dieses Beispiel zeigt, wie Codeabschnitte parallel ausgeführt werden

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";

Ausgabe

  • beginnen hallo welt für immer ende
  • Welt beginnen Hallo für immer Ende
  • fang hallo für immer das weltende an
  • für immer hallo Weltende beginnen

Da die Ausführungsreihenfolge nicht garantiert werden kann, können Sie eine der obigen Ausgaben beobachten.

OpenMP: Parallel für Schleife

Dieses Beispiel zeigt, wie eine Schleife in gleiche Teile aufgeteilt und parallel ausgeführt wird.

//    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
...

* Bitte achten Sie besonders darauf, die Größe des für Schleifen parallel verwendeten Vektors nicht zu ändern, da zugeordnete Bereichsindizes nicht automatisch aktualisiert werden .

OpenMP: Parallele Erfassung / Reduzierung

Dieses Beispiel veranschaulicht ein Konzept zum Durchführen einer Reduktion oder Erfassung mit std::vector und OpenMP.

Angenommen, wir haben ein Szenario, in dem wir möchten, dass mehrere Threads uns helfen, ein paar Sachen zu generieren. int wird hier der Einfachheit halber verwendet und kann durch andere Datentypen ersetzt werden.

Dies ist besonders nützlich, wenn Sie die Ergebnisse von Slaves zusammenführen müssen, um Segmentfehler oder Verstöße gegen den Speicherzugriff zu vermeiden und keine Bibliotheken oder benutzerdefinierte Sync-Container-Bibliotheken verwenden möchten.

//    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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow