it-swarm.com.de

OpenMP vs C++ 11-Threads

Im folgenden Beispiel dauert die Ausführung der C++ 11-Threads ungefähr 50 Sekunden, die der OMP-Threads jedoch nur 5 Sekunden. Irgendwelche Ideen warum? (Ich kann Ihnen versichern, dass dies immer noch zutrifft, wenn Sie echte Arbeit anstelle von doNothing leisten oder wenn Sie dies in einer anderen Reihenfolge tun, usw.) Ich arbeite auch auf einem 16-Kern-Computer.

#include <iostream>
#include <omp.h>
#include <chrono>
#include <vector>
#include <thread>

using namespace std;

void doNothing() {}

int run(int algorithmToRun)
{
    auto startTime = std::chrono::system_clock::now();

    for(int j=1; j<100000; ++j)
    {
        if(algorithmToRun == 1)
        {
            vector<thread> threads;
            for(int i=0; i<16; i++)
            {
                threads.Push_back(thread(doNothing));
            }
            for(auto& thread : threads) thread.join();
        }
        else if(algorithmToRun == 2)
        {
            #pragma omp parallel for num_threads(16)
            for(unsigned i=0; i<16; i++)
            {
                doNothing();
            }
        }
    }

    auto endTime = std::chrono::system_clock::now();
    std::chrono::duration<double> elapsed_seconds = endTime - startTime;

    return elapsed_seconds.count();
}

int main()
{
    int cppt = run(1);
    int ompt = run(2);

    cout<<cppt<<endl;
    cout<<ompt<<endl;

    return 0;
}
16
user2588666

OpenMP Thread-Pools für seine Pragmas (auch hier und hier ). Das Herauf- und Herunterspinnen von Fäden ist teuer. OpenMP vermeidet diesen Overhead. Alles, was es tut, ist die eigentliche Arbeit und das minimale Versetzen des Ausführungsstatus in den gemeinsamen Speicher. In Ihrem Threads-Code drehen Sie bei jeder Iteration einen neuen Satz von 16 Threads hoch und herunter.

24
aruisdante

Ich habe versucht, einen Code mit 100 Schleifen bei Auswahl des richtigen Threading-Frameworks zu erstellen, und es dauerte OpenMP 0.0727, Intel TBB 0.6759 und C++ - Threadbibliothek 0.5962 Millisekunden.

Ich habe auch das angewendet, was AruisDante vorgeschlagen hat.

void nested_loop(int max_i, int band)  
{
    for (int i = 0; i < max_i; i++)
    {
        doNothing(band);
    }
}
...
else if (algorithmToRun == 5)
{
    thread bristle(nested_loop, max_i, band);
    bristle.join();
}

Dieser Code scheint weniger Zeit in Anspruch zu nehmen als der ursprüngliche C++ 11-Threadabschnitt.

1
Cloud Cho