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.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich weiß nicht, welche Informationen Sie haben, aber parallelising eine unregelmäßige, stark synchronisiert Algorithmus mit kleinen Aufgaben zu den härtesten parallele Probleme, die man haben kann. Forschungsteams widmen sich solchen Aufgaben und begrenzte Beschleunigungen, oder nirgends mit ihm. Oft werden solche algorithmen funktionieren nur auf bestimmten Architekturen, die maßgeschneidert sind für die Parallelisierung und skurrile Gemeinkosten wie false-sharing wurden beseitigt, durch die Gestaltung der Datenstrukturen angemessen.
Einen Algorithmus, wie dies benötigt eine Menge Zeit und Mühe zu Profil, Messung und Betrachtung. Siehe zum Beispiel dieses Papier.
ww2.cs.fsu.edu/~flin/ppq_report.pdf
Nun, auf deine direkte Frage zu stellen, da Ihr Algorithmus ist hoch synchronisiert, und die Aufgaben sind klein, Sie erleben die Nebenwirkung von Daten Rennen. Entfernen Sie diese von Ihrem paralleler Algorithmus ist sehr schwierig, und niemand hier kann es für Sie tun.
So Ihre erste Anlaufstelle ist der Blick auf tools, die helfen können Sie erkennen, Daten Rennen wie Valgrind und der Intel thread checker.