QThread statt OpenMP?

Alles rund um die Programmierung mit Qt
m.mickey
Beiträge: 27
Registriert: 10. Januar 2010 23:01

QThread statt OpenMP?

Beitrag von m.mickey »

Hallo,
ich arbeite an einem GUI Projekt (unter Linux und Windows), das recht lange Berechnungen ausführt. Derweil wirkt die GUI fast wie tot, und das soll sich nun ändern.
Die Berechnungen bestehen aus vielen Schleifen, die nacheinander abgearbeitet werden müssen, und deshalb sind sie mit OpenMP parallelisiert. Nun wollte ich die GUI mittels QThreads in einen eigenen Thread auskoppeln, was von der Idee her auch zu funktionieren scheint, und unter Linux läuft es auch problemlos. Unter Windows (Mingw) bekomme ich einen libgomp1.dll error...
Nach etwas googeln scheint es daran zu liegen, dass QThreads auf Windows Threads zurückgreift und OpenMP auf POSIX Threads, und diese scheinen sich nicht zu vertragen. :-( (unter Linux nutzt QThreads auch POSIX, dort geht es)
Was würdet ihr empfehlen um eine aktive GUI zu erhalten?
Die Parallelisierung der Schleifen auf QThread portieren (doch wie? es sind viele und für jedes #pragma omp ne eine Klasse :-()?
Gibt es einen Workaround um QThread und OpenMP unter Windows gemeinsam zu benutzen? Anderer Compiler, welcher?
Ganz anderes Vorgehen?

Vielen Dank im Voraus.

Viele Grüße mickey
phlox81
Beiträge: 97
Registriert: 7. Juli 2009 12:30
Kontaktdaten:

Beitrag von phlox81 »

Evtl. mit den MS Compilern versuchen, die unterstützen auch OpenMP.

Ansonsten, der Mainthread ist eigentlich der GUI Thread, du wirst also wahrscheinlich sowieso in Probleme kommen, wenn du die GUI in einen anderen Thread "verpflanzt". Von daher könntest du natürlich den OpenMP Code durch QThread (oder boost::thread) ersetzen.

Kann dir aber nicht sagen, wie viel Aufwand das ist, und ob du den Code 1:1 so übernehmen solltest.

phlox
m.mickey
Beiträge: 27
Registriert: 10. Januar 2010 23:01

Beitrag von m.mickey »

Soweit ich weiß, unterstützt MS ... Express kein OpenMP und die anderen habe ich nicht zur Verfügung.

Die Gui soll schon weiter in Mainthread laufen, nur soll die Bearbeitung in einen anderen Thread und in dem sollen dann viele Schleifen mit OpenMP (oder eben anders) parallelisiert werden.

Wie würde man denn eine einfache for Schleife mit QThreads parallelisieren, geht das auch ohne eigene Klasse?

Viele Grüße mickey
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

m.mickey hat geschrieben:Soweit ich weiß, unterstützt MS ... Express kein OpenMP und die anderen habe ich nicht zur Verfügung.

Die Gui soll schon weiter in Mainthread laufen, nur soll die Bearbeitung in einen anderen Thread und in dem sollen dann viele Schleifen mit OpenMP (oder eben anders) parallelisiert werden.

Wie würde man denn eine einfache for Schleife mit QThreads parallelisieren, geht das auch ohne eigene Klasse?

Viele Grüße mickey
*gespannt auf den auftritt von AuE wartet*

Derweil könntest du dir das hier durchlesen:
Im Allgemeinen:
http://qt.nokia.com/doc/4.5/threads.html

und

http://qt.nokia.com/doc/4.5/qrunnable.html
http://qt.nokia.com/doc/4.5/qthread.html
http://qt.nokia.com/doc/4.5/qthreadpool.html

und insbesondere:
http://qt.nokia.com/doc/4.5/qtconcurrent.html
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

pfid hat geschrieben:
m.mickey hat geschrieben:Soweit ich weiß, unterstützt MS ... Express kein OpenMP und die anderen habe ich nicht zur Verfügung.

Die Gui soll schon weiter in Mainthread laufen, nur soll die Bearbeitung in einen anderen Thread und in dem sollen dann viele Schleifen mit OpenMP (oder eben anders) parallelisiert werden.

Wie würde man denn eine einfache for Schleife mit QThreads parallelisieren, geht das auch ohne eigene Klasse?

Viele Grüße mickey
*gespannt auf den auftritt von AuE wartet*
Was möchtest hören? ;-)


Ich fang mal an wie immer... du kannst auch dein GUI von QRunnable ableiten und dort eine run Methode implementieren...so kommst um die eigene Klasse drum herum ;-) In dem Fal würde ich das aber für eine schlechte Idee halten. Wie oft machst diese Berechnungen? Selten ==> Threads, häufig: Threadpool und runnable

@pfid: Gut so?
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

AuE hat geschrieben:
pfid hat geschrieben:
m.mickey hat geschrieben:Soweit ich weiß, unterstützt MS ... Express kein OpenMP und die anderen habe ich nicht zur Verfügung.

Die Gui soll schon weiter in Mainthread laufen, nur soll die Bearbeitung in einen anderen Thread und in dem sollen dann viele Schleifen mit OpenMP (oder eben anders) parallelisiert werden.

Wie würde man denn eine einfache for Schleife mit QThreads parallelisieren, geht das auch ohne eigene Klasse?

Viele Grüße mickey
*gespannt auf den auftritt von AuE wartet*
Was möchtest hören? ;-)


Ich fang mal an wie immer... du kannst auch dein GUI von QRunnable ableiten und dort eine run Methode implementieren...so kommst um die eigene Klasse drum herum ;-) In dem Fal würde ich das aber für eine schlechte Idee halten. Wie oft machst diese Berechnungen? Selten ==> Threads, häufig: Threadpool und runnable

@pfid: Gut so?
Naja ich bin davon ausgegangen dass du ihm direkt einen QThreadPool mit Sonderausstattung und allem verkaufst :D

[edit] Hrhr :D
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

Kommt immer drauf an... ;-) so verallgemeinern kann man das net! siehe Beitrag eins über deinem.
Wenn ich ständig nen Thread erstelle isses irgendwann sehr aufwendig und kostenintensiv. bei einmaliger berechnung kann er auch nen Thread nehmen.
m.mickey
Beiträge: 27
Registriert: 10. Januar 2010 23:01

Beitrag von m.mickey »

Erstmal: Danke!

Also die GUI steht und wird auch nicht großartig modifiziert, bis auf Usereingaben eben. Aber die Berechnungen werden eben nach jeder Usereingabe von neuem gestartet, also im Zweifelsfall sehr oft.

Ich hab die Links noch nicht gecheckt, aber wenn ich euch richtig verstehe, sollte ich mir den Threadpool anschaun. Damit kann ich dann QThread vermeiden? Weil gerade das macht ja scheinbar unter Windows das Problem, also das Mischen von OpenMP (pthreads) und QThread (Windowsthreads).

Hat eigentlich jemand genau so eine Kombi schon mal zum Laufen gebracht? Seht ihr Probleme bei der Verwendung von mingw (gcc 4.4.1)?

Viele Grüße mickey
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

Ich sehe den Grund für einen Mischmasch nicht ;-)
Aber ich habe auch keine Ahnung von openPM. Wenn es immer die gleiche Berechnung ist würde sich ein QRunnable sowohl für Win als auch für Unix anbieten. Ich kann dir nicht sagen in wie weit sich das mit openPM beisst. Aber ich würde von einer unix so und Win so Lösung abraten du dann 2 Sachen maintainen musst.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

- Windows unterstuetzt nur seine eigenen Threads .... "Posix Threads" kennt das eigentlich gar nicht.
Aber es gibt ne Lib, die die in Posix spezifizierten Thread commandos und snychronisations-objekte auf die windows Boardmittel mappt. ohne libpthread oder wie das ding heisst wirst also ned weiter kommen. und die lib iss sicher ned von M$ ...

Oder bringt VS 2008 oder höher da schon ne eigne kompatiblitaetslib mit ?

- ich kann mir ned vorstellen, das OpenMP auf eine kompatiblitaetslib setzt. die haengen sicher so tief am compiler, also werden die wahrscheinlich eher auf windows nativ Elemente setzen.

QThread und OpenMP sind 2 komplett unterschiedliche Ansaetze.
OpenMP versucht auf Performance und geringen overhaed bei ausnutzung der Kerne des Prozessors zu gehen.
Dabei kuemmert sich OpenMP um vieles selber.
Mit einem
#pragma omp parallel for
z.b siehst du auf Anhieb gar ned, was der compiler aus der naechsten for schleife macht ...
du kannst dich nur drauf verlassen, dass der das performante Ergebnisse aus deiner Plattform rausholt, wenn natuerlich OpenMP seitig alles richtig machst.

Bei QThread musst dich um alles selber kuemmern. wenn du 5 threads erzeugst, erzeugst du immer 5 threads, solnage die Plattform nur ueberhaupt threads untersteutzt. Ob die 5 threads sinnig sind, oder ob performancetechnisch nur 1 thread sinnvoller waer, das iss der QT wurscht, die macht was du sagst.
Der overhead iss auch viel groesser ....
Qthread nimmst wenn ned so auf das qaeuntschen performance ausbist, und dafuer lieber saubereren und wartbareren code haben willst.
OpenMP solltest nehmen, um ne Operation schnellstmoeglich durchn prozessor zu jagen.
Keiner wird auf die Idee kommen, die QT in nem FPS abhaengigen Spiel zu verwenden. aber OpenMP setzen sicher einige ein ...

Ich wuerd dein Problem aufteilen.
Deine langweirige operation in ne Dll packen, und die da mit OpenMP dein System voll auslasten lassen.

Auf der Applikationsseite kannst die QT dann verwenden .... und wenn deine Operation von aussen nur anstossen musst, und das ding dann mit events / callback sich selber meldet beim Aufrufer, brauchst da nicht mal eigene Threads erzeugen / kommst mit einem aus (brauchst aber trotzdem threadsicherheit und threadwechsel)
Wenn aber nen thread brauchst, der blockiert, aka aufs ende wartet, kannst den dann getrost als QThread erstellen.

Ciao ...
m.mickey
Beiträge: 27
Registriert: 10. Januar 2010 23:01

Beitrag von m.mickey »

@ AuE: ganz verstehe ich das noch nicht. Was soll ich mit dem QRunnable starten? Meinst du ich soll damit die OpenMP Parallelisierung ersetzen? Oder den Thread, oder den Bearbeitungsdurchlauf (den ich wie gesagt sehr oft starten muss, nach jeder Usereingabe...)

@RHBaum: Es ist sehr rechenintensiv und die Schleifen sind alle unterschiedlich uns müssen seriell abgearbeitet werden, deshalb ist denk ich OpenMP eine sehr gute Wahl. Ich brauch eben nur was um die GUI aktiv zu halten. Die Idee mit der dll (das sollte doch auf einen eigenen Prozess rauslaufen, oder?) find ich nicht schlecht, allerdings habe ich keine Ahnung wie das umzusetzen ist. Es muss einiges an Kommunikation stattfinden, Start/Stop, es müssen mehrere Speicherfelder in beide Richtungen übergeben werden und eine Klasse (abgeleitet von QSettings) die die Steuerinformationen enthält. Ist das alles effizient möglich? Gibt es dazu vielleicht ein einfaches Tutorial oder Beispiel?

Vielen Dank für eure Hilfe.

Viele Grüße mickey
phlox81
Beiträge: 97
Registriert: 7. Juli 2009 12:30
Kontaktdaten:

Beitrag von phlox81 »

Für sowas könntest du dir das Plugin Beispiel ansehen.
Dann kannst du auch mehrere Plugins schreiben, die das jeweils anders lösen.
http://doc.trolltech.com/4.6/tools-plugandpaint.html

Alternative wäre, es in 2 programme aufzuspalten, einen client, der die GUI hat, und einen server, der die Berechnung durchführt.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Ob er nen richtiges Plugin braucht, keine ahnung ...

Nen Plugin iss ja auch ne dll, nur mit Verwaltungsinfos. Ob er ne selbststaendige Verwaltung braucht ? ich bezweifle es.
Braucht man eigentlich nur, wenn man sehr flexibel zwischen "modulen" mit die teilweisse gleiche aufgaben loesen, umherschalten will. is meist der fall wenn man sein programm flexibel durch 3te erweitern lassen will.

Muss man immer genau ein Modul haben, was die aufgabe loest, und das modul soll zwar austauschbar, aber immer eins vorhanden sein, iss nen Plugin Imho scho overkill.

QPlugin wuerd ich eher nicht benutzen !
Weil QPlugin schreibt IMHO schnittstellen vor, die QT abhaengig sind, ergo kriegst Du QT abhaengigkeiten in die Dll -> schraenkt den kompiler ein.

Ich wuerd im gegenteil das Interface sehr einfach halten so das man es als reines C Interface implementieren kann
Das bringt den riesen vorteil, das die schnittstelle compilerabhaengig binaer standardisiert ist !
er ist nicht bei dll und exe nimmer auf die binaerkompatiblitaet der kompiler angewiessen, ergo er kann die dll mit komplett anderen compilerflags bauen, und er kann sogar nen anderen kompiler fuer die dll verwenden.
Grad im hinblick auf openMP. Wer openMP verwendet, will performance. Und bei unterschiedlichen plattformen sind compiler unterschiedlich performant ... bzw es laesst sich ne menge mehr rausholen.
er kann z.b. die Dll für intel plattformen mit dem intel kompiler bauen, welcher opnenMP wesentlich besser unterstuetzt .... und muss trotzdem ned sein ganzes buildsystem auf intel umstellen ....

Ciao ...
m.mickey
Beiträge: 27
Registriert: 10. Januar 2010 23:01

Beitrag von m.mickey »

Ok, es scheint also momentan kein Weg um einen eigenen Prozess herum zu führen. Das mit dem Plugin ist wirklich etwas überladen für meine Zwecke, zumal es eh schon ne Menge Arbeit wird.

Ich wäre noch für Hinweise dankbar, wie ich Zeiger auf Felder und eine Settingsklasse zwischen den beiden Prozessen austauschen kann.

Vielen Dank für eure Mühe.

Viele Grüße mickey
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Ok, es scheint also momentan kein Weg um einen eigenen Prozess herum zu führen.
Neneneene so war dass ned gemeint.
Bluehen kann Dir das zwar auch, falls intel/OpenMP und MS/Qt irgendwelche ProzessEnvoroments anders erwarten, aber versuchen wurd ichs definitiv erst mal InProzess, also mit einem prozess.

Wenn die Dll mit loadlibrary holst, dir den funktionspointer mit getProcAdress besorgst, und die Funktion mittels dem funktionspointer callst, bleibt das inprozess. das heisst du kannst als parameter zeiger auf speicherbereiche uebergeben, und die dll, wenn die weiss was dahinter steht, kann damit auch was anfangen. Darf sich halt durch multithreading nur ned gegenseitig rauswerfen.

Wenn die schnittstelle ne C schnittstelle iss, kannst zum bauen der DLL nen ganz anderen kompiler nehmen, als fuer die exe, und das ist der ja der Clou. Mit OpenMP hab ich da keine erfahrung, aber VS 2005 mit ner mittles mingw compilierten c-dll funktioniert wunderbar ^^

Ciao ...
Zuletzt geändert von RHBaum am 15. Januar 2010 16:32, insgesamt 1-mal geändert.
Antworten