Qt Threads aus verschiedene Core verteilen

Alles rund um die Programmierung mit Qt
RavenIV
Beiträge: 267
Registriert: 21. Januar 2009 14:24
Wohnort: Waldshut

Qt Threads aus verschiedene Core verteilen

Beitrag von RavenIV »

Hallo 'Gemeinde

Ich habe eine Anwendung, die auf 5 Threads verteilt ist.
Ein GUI-Thread und 4 Worker.
Programmiert ist das in Python (GUI) und C++ (Worker).

Dazu haben wir einen PC mit einem Multicore-Prozessor unter WinXP-SP3.

Nun habe ich aber festgestellt, dass ein Core fast glüht und die anderen drei Cores sich langweilen.

Wie kann ich es schaffen, dass die vier Worker-Threads auf die vier Cores verteilt werden?

Quellcode darf ich leider keinen Posten wegen Geheimhaltung. :-(

Danke
Linux, das längste Text-Adventure aller Zeiten
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

erst mal sicherstellen, das auch alle 4 threads gleichmaessig arbeiten, und nicht einer rackert und die restlichen 3 auf den einen warten ....
Kannst du das zu 100% ausschliessen, gibts weitere optionen.

es gibt winapi funktionen, mit denen man mehr kontrolle ueber die threads hat. Notfalls im c++ teil auf die qt verzichten und c++ winapi programmieren.

mit paar schmutzigen hacks kommst auch auf die threadID von den QThreads und kannst ueber die winapi da bissi was steuern.

Nachteil: du verlierst die plattformunabhaengigkeit oder musst die selber einprogrammieren.

weiterhin.... wie komplex ist die synchronisation zwischen den einzelnen threads und wie extensiv der datenaustausch.
Iss das ziemlich trivial, dann wuerd ich statt multithreading eh auf multiprozessing ausweichen, damit kommen die meisten BS auch besser klar (besonders unixe). windows verteilt die prozesse viel besser auf unterschiedliche kerne als bei threads ....
(andere berichten anders, aber bei uns hier auf mehreren rechnern mit DualCores / quadcores, windows XP SP2, qt 4.5 momentan, visual studio 2005, kein mp support, legt er alle threads von einem prozess immer standardmaessig auf einen Kern. erst wenn ich manuell eingreife, bekomm ich beide kerne ausgelastet. und nein ich mein ned den compiliervorgang, da verwendet er eh immer nur 1 kern, sondern wirklich das ausfuehren des programms)

Ciao ...
DarkWotan
Beiträge: 65
Registriert: 18. Mai 2006 10:03

Beitrag von DarkWotan »

RHBaum hat geschrieben:und nein ich mein ned den compiliervorgang, da verwendet er eh immer nur 1 kern
Hat zwar nichts mit dem Thema zu tun, aber das muss ich jetzt los werden:
Probier mal den Schalter /MP bei den Compilereinstellungen ;-)
RavenIV
Beiträge: 267
Registriert: 21. Januar 2009 14:24
Wohnort: Waldshut

Beitrag von RavenIV »

Die vier Worker machen alle das selbe, jedoch mit unterschiedlichen Kameras. Wir haben also vier identische Kameras und die Worker untersuchen die Bilder der Kameras.
Kommunikation der Threads besteht nicht.
Die Threads werden gestartet, arbeiten eine gewisse Zeit, geben ein Ergebnis zurück und beenden sich.

Plattformunabhängigkeit ist wichtig, weil die nächste Version der Software unter Linux laufen soll.

Gibt es Tips, Ideen, wie wir die SW von mehreren Threads zu mehreren Prozessen umbauen können?
Linux, das längste Text-Adventure aller Zeiten
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Spannend.. weil mich das auch interessierte, habe ich mal was gebastelt. ergebnis:

1. 2 QThreads arbeiten (auf meinem Ubuntu, Qt 4.4.3) in _einem_ Core.
2. 2 QRunnables in einem QThreadPool arbeiten auf _zwei_ Cores.

Da hättest du die Lösung ;)
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

@solarix: Deine erste Aussage kann ich nicht wirklich nachvollziehen - wenn es wirklich so ist liegt es aber sicherlich nicht an Qt sondern an irgendwelchen OS-spezifischen Dingen / Einstellungen.

@RavenIV: Bist Du wirklich sicher das deine Verarbeitungen auch in den Threads passieren und nicht im MainThread? Sowas geht schnell wenn man nicht korrekt programmiert. Schau Dir lieber mal mit QThread::threadId() an in welchen Thread genau die Abarbeitung abläuft.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
RavenIV
Beiträge: 267
Registriert: 21. Januar 2009 14:24
Wohnort: Waldshut

Beitrag von RavenIV »

Ja, ich bin sicher.
In der Logdatei sieht man, dass abwechselnd Einträge von "Worker1" bis "Worker4" kommen.

Wo und wie kann ich überprüfen, ob die Threads auch richtig gestartet werden?
Ich habe Teile der Software von einem Kollegen (der nicht mehr da ist) übernommen.
Linux, das längste Text-Adventure aller Zeiten
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

@Christian81: Ich war selbst überrascht. Zwei QThreads mit einem "while (1);" ergeben bei meinem (Default-Ubuntu Intrepid/Linux 2.6.27-11) nur Halblast. In einem ThreadPool Volllast. "top" lässt da kein Zweifel.. Allerdings bin ich deiner Meinung: das muss OS-spezifisch sein. Ich wollte das nur erwähnen, weil Raven ja Linux als Zielsystem hat..

@RavenIV: "Wo und wie kann ich überprüfen, ob die Threads auch richtig gestartet werden?" Ein Mini-Benchmark kannst du doch in etwa 20s selbst erstellen... einfach 4 Threads mit "while (1);" starten.. wenn dann der Rechner Volllast hat, ist dein Programm faul.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

RavenIV hat geschrieben:Ja, ich bin sicher.
In der Logdatei sieht man, dass abwechselnd Einträge von "Worker1" bis "Worker4" kommen.
Nur weil alle 4 Objekte was ausgeben heißt es nicht dass dies auch in 4 verschiedenen Threads passiert... :roll:

@Solarix:

Code: Alles auswählen

#include <QCoreApplication>
#include <QThread>

class MyThread : public QThread
{
  public:
    MyThread() {}
    ~MyThread() {}
    
    virtual void run()
    {
        while(1) {
          // do nothing
        }
    }
};

int main(int argc, char**argv)
{
  QCoreApplication app(argc, argv);
  
  MyThread t1;
  MyThread t2;
  t1.start();
  t2.start();
  
  return app.exec();
}
'top' zeigt mir 195% CPU-Last bei 2 Cores - Vollast würde ich sagen.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Ryu1991
Beiträge: 27
Registriert: 11. Mai 2009 09:29

Beitrag von Ryu1991 »

Wenn die Threads eh unabhängig sind.
Warum machst du dann nicht 4 Einzelne Programme draus. Dann kannst du (zumindest unter Windows) jedem Programm einen Kern zuweisen.
Und das Bild-Signal (Ich geh mal davon aus, weil du Kameras erwähntest) kannst du ja per Shared-Memory oder so an deine GUI weiterleiten.

EDIT: Habe gerade gesehen, dass deine GUI und die QT Units nicht das selbe Programm sind, also isses ja noch einfacher, und du müsstest statt einem Signal halt 4 annehmen.
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

@Christian81: Genau das gleiche ergibt bei mir 100% (=Halblast, 50% Idle-Time). Spannend, was fuer eine Linux-Version hast du?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

@Solarix: bin openSUSE-Fan :wink:
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
RavenIV
Beiträge: 267
Registriert: 21. Januar 2009 14:24
Wohnort: Waldshut

Beitrag von RavenIV »

Um ein paar Vermutungen / Unklarheiten zu beseitigen:

- Zielplattform ist (noch) WinXP, Linux kommt wohl erst Ende Jahr.
- GUI und die Worker laufen in einer gemeinsamen Executable.
- Die Worker hängen eng mit der GUI zusammen, sie werden von der GUI gestartet, bekommen Arbeit zugewiesen, melden der GUI das Ergebnis und beenden sich anschliessend. Beim nächsten zu untersuchenden Werkstück beginnt das Spiel von vorne.
- das Logging kommt definitiv von den 4 Threads, weil jeder Thread eine eigene ID hat für das Log.
- Abhängigkeiten der Worker untereinander gibt es nicht.

Werde mal mit nem Mini-Programm das System testen.

Danke schon mal.
Weitere Ideen / Vorschläge nehme ich gerne an.
Linux, das längste Text-Adventure aller Zeiten
RavenIV
Beiträge: 267
Registriert: 21. Januar 2009 14:24
Wohnort: Waldshut

Beitrag von RavenIV »

Ich habe jetzt ein kleines Mini-Programm erstellt.
Es beinhaltet im Groben den Code von Christian81 plus eine kleine GUI drum herum, damit man die Anzahl Threads einstellen kann.

Bei einem "normalen" Intel Core 2 Q6600 Quad-Core sieht man nicht das erwartete Ergebnis, dass einzelne Cores mit 100 % laufen und der Rest mit 0 %, sondern es werden immer alle Cores in die Ausführung einbezogen.
Nur beim Intel Core i7 sieht man, dass wirklich jeder Thread auf einem Core ausgeführt wird.

Code habe ich angehängt.
Dateianhänge
Threadtest.zip
(13.22 KiB) 173-mal heruntergeladen
Linux, das längste Text-Adventure aller Zeiten
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Code: Alles auswählen

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
22355 ehrliche  20   0  237m  19m  14m S  195  1.0   0:30.81 Threadtest
-> 195%CPU - Last bei 2 Threads. Also wie gewünscht.
Kauf Dir ein ordentliches OS - das liegt definitiv nicht an Qt :)
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Antworten