Parallel Dijkstra

Ich bin mit OpenMP zu machen, parallele version des Dijkstra-Algorithmus. Mein code besteht aus zwei teilen. Erste Teil ist die Ausführung durch einen thread (master). Dieser thread wählt neuen Knoten aus der Liste. Der zweite Teil ist die Ausführung von anderen threads. Diese threads ändern Entfernungen von Quelle zu anderen Knoten. Leider in meinem code ist Fehler, weil eine von vielen threads das ausführen der zweiten Teil plötzlich "verschwinden". Wahrscheinlich gibt es ein problem mit der Datensynchronisation, aber ich weiß nicht wo. Ich wäre dankbar, wenn jemand mir sagen könnte, wo liegt mein Fehler. Hier ist der code:

map<int, int> C;
map<int, int> S;
map<int, int> D;
int init;
int nu;
int u;
int p = 3;//omp_get_num_threads();
int d;
int n = graph->getNodesNum();

#pragma omp parallel shared(n, C, d, S, init, nu, u, D, graph, p) num_threads(p)
{
    int myId = omp_get_thread_num();
    if (myId == 0)
    {
        init = 0;
        nu = 0;

        u = to;
        while (init < p - 1)
        {
        }

        while (u != 0)
        {
            S[u] = 1;
            while (nu < p - 1)
            {
            }
            u = 0;
            d = INFINITY;
            for (int i = 1; i <= p - 1; ++i)
            {
                int j = C[i];
                if ((j != 0) && (D[j] < d))
                {
                    d = D[j];
                    u = j;
                }
            }
            nu = 0; 
        }
    }
    else
    {
        for (int i=myId; i<=n; i += p-1)
        {
            D[i] = INFINITY;
            S[i] = 0;
        }

        D[u] = 0;

        ++init; 
        while (init < p-1)
        {
        }
        while (u != 0)
        {
            C[myId] = 0;
            int d = INFINITY;

            for (int i = myId; i<=n; i+=p-1)
            {
                if (S[i] == 0)
                {
                    if (i != u)
                    {
                        int cost = graph->getCostBetween(u, i);
                        if (cost != INFINITY)
                        {
                            D[i] = min(D[i], D[u] + cost);
                        }
                    }
                    if ((d > D[i])) 
                    {                           
                        d = D[i];
                        C[myId] = i;
                    }
                }
            }
            ++nu;
            while (nu != 0)
            {
            }   
        }
    }       
}

}

  • das klingt wie ein bodenloser Weise zu parallelisieren, eine inhärent sequentiellen Algorithmus. Warum machst du das? die Kosten der übergabe der vertex-ein thread sollte in etwa gleich, die der Aktualisierung der Kosten.
  • Ich muss vorbereiten, parallel-version zu zeigen, dass Dijkstra schneller sein können, wenn wir mehr Kerne. Ich weiß, dass Dijkstra ist schwer zu parallelisieren und in der Regel speedup ist niedriger als 1. Allerdings fand ich einige Informationen, es ist der Weg zur Umsetzung dieses Algorithmus mit speedup 1,2-1,4. Mein code vorhanden, somit in diesem moment will ich zu erkennen, Fehler.
  • Die "speed-up" auf eine Umsetzung hängt von der Anzahl der parallel verwendeten Prozessoren, so verstehe ich nicht, was bedeutet diese zahlen bedeutet. Wahrscheinlich ist der speed-up, hängt von der "Dichte" Ihres Diagramms und in wie viel Zeit verbringen Sie vorbei Ecken herum. Es ist eine sehr feinkörnigen Ansatz, so müssen Sie eine wunderbar abgestimmte Umsetzung zu erreichen, eine version, die ist vernünftig schneller (wenn schneller) w.r.t. die sequentielle Umsetzung. Wie für Ihre Umsetzung, ich verstehe nicht, wo dein main-thread löst Knoten gelockert werden, um andere threads.
InformationsquelleAutor mchrobok | 2012-06-20
Schreibe einen Kommentar