D
Hallo zusammen.
Ich arbeite im Moment an einem Projekt, bei dem wir openMP für die Parallelisierung einsetzen und bekomme offenbar Deadlocks.
Ich habe in der Anwendung 2 verschiedene Threads, ThreadA und ThreadB (erstellt mit einer eigenen Bibliothek, die soweit ich weiß auf Posix-Threads aufsetzt, also noch nichts im openMP).
Außerdem existiert eine Funktion, FunktionA, die mehrmals hintereinander mit openMP parallelisierte for-Schleifen durchgeht, welche critical sections enthalten.
ThreadA ruft nun alle 30 Sekunden diese FunktionA einmal auf.
ThreadB wiederum enthält eine parallele for-Schleife, die wiederum eine sequentielle for-Schleife enthält, welche wiederum FunktionA aufruft.
Ich versuche das mal in pseudo-Code zu zeigen:
FunktionA:
FunktionA()
{
parallel-for
{
...
critical {...}
...
}
parallel-for
{
...
critical {...}
...
critical {...}
...
}
parallel-for
{
...
critical {...}
...
}
}
ThreadA:
while(true)
{
FunktionA();
wait(30000);
}
ThreadB:
parallel-for
{
for(i = 0 bis x)
{
FunktionA();
}
}
(Es erfolgt also eine verschachtelte Parallelisierung in ThreadB)
Die Datenbasis der Aufrufe von FunktionA sind zwischen ThreadA und ThreadB unterschiedlich. Innerhalb von ThreadB kann die äußere Schleife auch parallel arbeiten, die innere muss sequentiell abgearbeitet werden, die Daten bauen also aufeinander auf.
Was nun passiert:
ThreadA wird zu Programmstart einmal ausgeführt. Danach startet ThreadB. Dieser braucht für die Abarbeitung recht lange, sodass nach 30 Sekunden ThreadA wieder triggert, während ThreadB noch rechnet.
Dabei passiert es, dass ThreadA direkt in der ersten parallel-for hängen bleibt. Und zwar noch vor der ersten anweisung (also auch nicht in der critical section), die Schleife wird also gar nicht erst angefangen.
Außerdem bleiben einige (aber nicht alle) omp-Threads aus Thread B gleichzeitig ebenfalls mitten in FunktionA hängen.
Wenn ich in den parallel-for-Schleifen von FunktionA num_threads auf 1 setze, funktioniert es. Wenn sie größer ist, kommen die Deadlocks, unabhängig davon, ob ich omp_nested auf 0 oder 1 setze. Ich habe die Vermutung, dass beim Eintritt in die parallel-fors zwischen ThreadA und ThreadB irgendwelche impliziten Barrieren oder so gesetzt sind...
Jeder Thread für sich funktioniert ebenfalls.
Das ganze Programm ist natürlich etwas komplexer als hier beschrieben und ich bin selbst nicht für die inneren Programmteile verantwortlich, also kann ich nicht viel genauer mit dem Code werden, oder ihn gar komplett umstellen.
Meine Fragen:
Als erstes natürlich, was ist falsch?
Da dies aber vermutlich nicht so leicht zu beantworten ist, kann man überhaupt grundätzlich pThreads und openMP vermischen? Und wenn ja, dürfen die Threads dann dieselbe parallelisierte Funktion aufrufen, oder behaken die sich dann gegenseitig, weil sie ihre Variablen auch Threadübergreifen sharen?
Kann mir irgendjemand helfen?
Vielen Dank schonmal für eure Geduld.
Walli
/edit: Wir benutzen übrigens gcc Version 4.3, also openMP Version 2.5. Könnte das Problem mit openMP 3.0 evtl behoben werden?