Multithreading und Multicore

Hallo,

wenn ich von einem Prozess mehrere Threads abspalte (CreateThread), nutzen die dann die Leistung von Multicore-Prozessoren besser als wenn die Aufgaben sequentiell abgehandelt werden?

Ich hab das mal versucht, komme aber zu keinen schlüssigen Ergebnissen: Eich berechne mit einem sehr einfachen Algorithmus ein Apfelmännchen (das ist die Gesamtaufgabe, die CPU soll halt was zu rechnen haben). Nun habe ich das komplette Bild in 2, 4, usw. Teile zerlegt und lasse jedes Teilbild in einem eigenen Thread rechnen. Im Hauptprogramm warte ich auf alle Threads (WaitForMultipleObjects) und baue dann aus den Teilbildern das Gesamtbild zusammen.

Ein 800x800 Pixel-Bild mit 1000 Recheniterationen pro bild dauert auf meinem Quadcore ca. 4 Sekunden, und das ist recht unabhängig von der Zahl der Threads (bis zu 100 habe ich probiert), die an diesem Problem arbeiten. Kann das sein?

LG
Jochen

Moien

wenn ich von einem Prozess mehrere Threads abspalte
(CreateThread), nutzen die dann die Leistung von
Multicore-Prozessoren besser als wenn die Aufgaben sequentiell
abgehandelt werden?

Ja.

Allerdings muss das Programm auch tatsächlich mit mehreren Threads arbeiten. Es gibt ein paar Situationen (Debug-Mode, manche VMs) in denen alle Programm-threads auf die gleiche CPU geschoben werden. Dann hilft es nicht.

Da du keinerlei Angaben zum Betriebssystem, der Sprache oder der Entwickelungsumgebung machst war das auch schon alles was man sagen kann.

Ein 800x800 Pixel-Bild mit 1000 Recheniterationen pro bild
dauert auf meinem Quadcore ca. 4 Sekunden, und das ist recht
unabhängig von der Zahl der Threads (bis zu 100 habe ich
probiert), die an diesem Problem arbeiten. Kann das sein?

Eigentlich nicht, Apfel ist recht einfach zu splitten. Allerdings braucht man auch nur 4 Threads um einen Quad auszulasten.

Was sagt eigentlich die Lastanzeige deines OS zur Belastung der einzelenen Kerne?

cu

Hallo,

wenn ich von einem Prozess mehrere Threads abspalte
(CreateThread), nutzen die dann die Leistung von
Multicore-Prozessoren besser als wenn die Aufgaben sequentiell
abgehandelt werden?

Das hängt von der Thread-Implementierung ab.

Grüße,
Moritz

Tach,

Allerdings muss das Programm auch tatsächlich mit mehreren
Threads arbeiten. Es gibt ein paar Situationen (Debug-Mode,
manche VMs) in denen alle Programm-threads auf die gleiche CPU
geschoben werden. Dann hilft es nicht.

Aha!

Da du keinerlei Angaben zum Betriebssystem, der Sprache oder
der Entwickelungsumgebung machst war das auch schon alles was
man sagen kann.

Ich wollte ertmal nicht zu speziell werden. Aber da Du danach fragst: Win XP Prof SP3 (32bit), Delphi 7. Thread-Implementierung direkt über die Windows-API (kein TThread-Objekt).

Was sagt eigentlich die Lastanzeige deines OS zur Belastung
der einzelenen Kerne?

Das schwankt ganz beträchtlich. Auch mit einem Thread werden mal mehr mal weniger Kerne beansprucht. In der Summe geht das mal bis 85% hoch, unabhängig von der Zahl der Threads. Bei Single-Thread ist es auch schon passiert, dass die Summe nicht über 25% steigt, das habe ich bei den Multi-Thraeds nicht beobachtet. Aber wie gesagt: Meist werden auch mit einem Thread mehrere Kerne belastet. (lt. Windows Task-Manager).

Danke & LG
Jochen

Hallo nochmal,

ich habe das Problem identifiziert:

Ich hatte eine TBitmap-Variable im Thread verwendet, und dort über die Eigenschaft Canvas die Pixelfarben zu setzen. Dabei benutzt Delphi aber offensichtlich einen Prozess-gemeinsame Resource, die immer als CriticalSection geschützt ist. Ich vermute, da warten die Threads dann immer aufeinander, bis die mal wieder ein Pixel malen dürfen. Ich habe die Bitmaps rausgeschmissen und speichere die Ergebnisse in einem Integer-Array. Damit erkenne ich nun deutlich das erwartete Verhalten:

  • ein Thread: 25%-CPU-Auslastung, 100% Zeitbedarf
  • zwei Threads: 50%-CPU-Auslastung, 50% Zeitbedarf
  • vier und mehr Threads: 100%-CPU-Auslastung, 25% Zeitbedarf

Alles gut.

Danke nochmal, hat sich also alles geklärt!

LG
Jochen

PS: Bei weniger als 4 Threads sieht man, dass ein Thread nicht kontinuierlich von einem Kern gerechnet wird. Ist es u.U. möglich und sinnvoll, die Ausführung eines Threads an einen Kern zu binden, um zB. unnötige Datentransfers zwischen den CPU-Caches zu vermeiden?

Moien

Bei weniger als 4 Threads sieht man, dass ein Thread nicht
kontinuierlich von einem Kern gerechnet wird. Ist es u.U.
möglich und sinnvoll, die Ausführung eines Threads an einen
Kern zu binden, um zB. unnötige Datentransfers zwischen den
CPU-Caches zu vermeiden?

Jein: deine Threads sind nicht die einzigen auf dem System. Deshalb muss es immer wieder Wechsel zwischen deinen und den Systemthreads geben. Dadurch kann einer von deinen schonmal die CPU wechseln.

Aber das Problem mit den Cache ist eher minimal. Die Vorteile durch feste Zuordnungen liegen bei 95% der Problemstellungen unter Messgrenze. Das echte Problem kommt erst bei NUMAs. Aber die Q-Serie von Intel ist noch eine SMP, genauso wie die i7.

cu

Hab Dank!

LG
Jochen