Laden...

[Multithreading] Frage zu einer Idee / zum Verständnis

Erstellt von 1nf1n1ty vor 15 Jahren Letzter Beitrag vor 15 Jahren 1.954 Views
1nf1n1ty Themenstarter:in
286 Beiträge seit 2007
vor 15 Jahren
[Multithreading] Frage zu einer Idee / zum Verständnis

Hallo zusammen,

ich habe vor mich in nächster Zeit näher mit Multithreading außeinander zusetzen und hab dabei auch schon ein Problem gefunden, welches man sich anschauen könnte. Stellt euch vor ihr habt eine Kollektion mit 1000 Bitmaps und möchtest diese möglichst schnell in JPEGs umwandeln. Dazu würde ich zuerst eine Liste mit Dateien erstellen.

Nun zum eigentlichen Problem: Wenn man nun eine Multicore CPU hat möchte man natürlich auch die vorhandene Rechenleistung nutzen. Dafür müsste ich ja dann einen Threadpool erstellen, der mir eine Anzahl an Threads erzeugt. Bei einem Quad-Core möchte ich dabei nur 4 Threads haben (wohlgemerkt 4 arbeitende, mir ist klar das ich noch einen für den GUI und vielleicht noch einen für irgendwelche kleineren Aufgaben brauchen kann). Wie würde man jedoch erkennen welches Bild bereits komprimiert ist? Es könnte ja sein die Bilder haben unterschiedliche Größen, d.h. die Bearbeitungszeit ist unterschiedlich. Es soll aber möglichst effizient sein. Demnach wäre die Lösung das der erste Thread Bild 1, 5, 9 ... der zweite 2,6,10 etc. komprimiert zwar eine Lösung, jedoch keine optimale.

Eine andere Idee die ich hatte wäre entweder ein Counter, der das als nächstes zu komprimierende Bild angibt und immer erhöht wird, sobald ein Thread sich so eines aus der Liste geholt hat oder zu jedem Bild zusätzlich eine Variable speichern, die angibt ob das Bild bereits geladen und komprimiert wurde. Dabei stellt sich für mich die Frage, ob sich die einzelnen Threads dabei möglicherweise in die Quere kommen können mit den Variablen, sprich: 2 Threads versuchen das gleiche Bild zu laden/komprimieren. Kann sowas passieren und wenn ja, wie würde man dem vorbeugen?

Der letzte Gedanke dazu: Die Bilder müssen ja nach der Komprimierung gespeichert werden. Dies geschieht in der Regel auf die Festplatte. Allerdings ist es nicht so effizient, wenn 4 Threads nach der Komprimierung gleichzeitig auf die Platte schreiben, da zum Einen der Zugriff verlangsamt wird, weil der Lesekopf dauernd hin und her springt und zum Anderen die Daten dann möglicherweise fragmentiert werden.
Meine Idee: Ein zusätzlicher Thread, der darauf wartet, dass ein anderer ihn anstösst und ihm sagt er soll das Bild nun auf die Festplatte schreiben.

Ich würde gerne eure Meinung und Erfahrungen zu diesem Thema hören und ggf. Verbesserungsvorschläge meiner Idee.

Grüße

Marco

F
240 Beiträge seit 2006
vor 15 Jahren

Du könnstest die SyncQueue<T> von herbivore (Applikation mit Warteschlange) benutzen, sodass du diese am Anfang mit Dateipfaden füllst, und dann x Threads starten, die sich dann automatisch ein Pfad holen, das Bild konvertieren und speichern. Das Speichern könntest du natürlich auch wieder über eine SyncQueue machen damit ein anderer Thread die Bilder dann speichert.

193 Beiträge seit 2007
vor 15 Jahren

Hallo,

habe sowas ähnliches gemacht.

Ich würde alle Bilder, bzw. die Pfade der Bilder in eine generiche Liste schreiben.
Der Zugriff auf diese Liste erfolgt in einer eigenen Methode, die intern das lesen
per lock regelt, so daß immer nur ein aufrufender Thread an die liste kommt.
(Übernimmt der Thread das Umwandeln dann kannste den Pfad in der Methode aus der Liste nehmen)

Das speichern kann genauso erfolgen.

Alle Ressource auf die von verschieden Threads zugegriffen wird, würde ich über
das lock schützen.

**:::{style="color: darkblue;"}If debugging is the process of removing bugs, then programming must be the process of putting them in.){darkblue}** Dijkstra
1nf1n1ty Themenstarter:in
286 Beiträge seit 2007
vor 15 Jahren

Hallo zusammen,

das sind schonmal 2 recht gute Ansätze 🙂 Vielen Dank schonmal, das werde ich mir auf jeden Fall mal anschauen. Noch eine Sache: Sollte ich dem Benutzer besser die Wahl lassen wieviele Threads er möchte oder wäre es besser dies automatisch zu erkennen (CPU Analyse). Gibts vom .NET Framework da vielleicht eine Methode die erkennt wieviele CPUs der Anwender zur Verfügung hat?

Grüße Marco

3.511 Beiträge seit 2005
vor 15 Jahren

Die Anzahl der Prozessoren bekommst du über Environment.ProcessorCount.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

3.971 Beiträge seit 2006
vor 15 Jahren

CPU-Lastige Programme wie Video-Verarbeitung/Umwandlung bieten dem Benutzer meißt an, die Anzahl der zu verwendeten Threads selbst zu bestimmten. Ich denke Environment.ProcessorCount ist dafür ein guter Default-Wert

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

998 Beiträge seit 2007
vor 15 Jahren

Also die Idee mit der generischen List finde ich persönlich nicht so gut wie die mit der Queue, weil die Queue nur mal für genau soetwas gedacht ist g

Mal eine Frage meinerseits, wenn ich 2 Threads starte, werden die auch automatisch auf meiner beiden Prozessoren verteilt? Geschieht das explizit oder implizit?

Gruß David

V
86 Beiträge seit 2008
vor 15 Jahren

Also du kannst dir auch mal folgendes anschauen: Optimieren von verwaltetem Code für Mehrkerncomputer
Mittlerweile gibts auch noch Parallel.ForEach, was wirklich sehr gut und performant ist.

[EDIT]Hier noch ein aktueller Link zu der Library: Microsoft Parallel Extensions to .NET Framework 3.5, June 2008 Community Technology Preview
In der zusätzlich angebotenen Hilfe sind sehr gute Beschreibungen und Codesnippets.

3.971 Beiträge seit 2006
vor 15 Jahren

Wie Threads auf die CPUs/Kerne verteilt werden hängt von der verwendete Technologie (Parallel Fx Library) und vom Betriebssystem ab.

Hast du beispielsweise 1 Thread und 2 Cores/CPUs verteilt Windows die Last zu 50% auf beiden Cores und nicht wie vllt. erwartet zu 100% auf einem Core.

Schöner Einstieg in das Thema ist auch in der aktuellen DOT NET PRO Ausgabe 09.2008 zu finden.

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

998 Beiträge seit 2007
vor 15 Jahren

Also könnte ich nicht explizit sagen das Thread X auf Core 1 und Thread Y auf Core 2 starten soll?!?

Wenn ich ein Programm mit nur einem Thread erzeuge und dort eine Endlosschleife erzeuge, geht die CPU-Last bis maximal 50% hoch, müssten es nach deiner Beschreibung dann nicht 100% sein?

Danke für den Tip mit der dot net pro, hoffe sowas gibt hier beim Zeitschriftenhändler (Habe nur das dot net magazin aboniert).

Gruß David

1nf1n1ty Themenstarter:in
286 Beiträge seit 2007
vor 15 Jahren

Hallo zusammen,

diese Parallel.Foreach Geschichte klingt wirklich sehr interessant. Ich vermute aber mal, dass diese nicht mit .NET 2.0 funktioniert, sehe ich das richtig?

Grüße

Marco

3.511 Beiträge seit 2005
vor 15 Jahren

Ich vermute aber mal, dass diese nicht mit .NET 2.0 funktioniert, sehe ich das richtig?

Jepp. Die Parallel Extensions hauen nur mit dem 3.5er Framework hin.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

1nf1n1ty Themenstarter:in
286 Beiträge seit 2007
vor 15 Jahren

Hallo zusammen,

Jepp. Die Parallel Extensions hauen nur mit dem 3.5er Framework hin.

Hmm... schade. Das 2.0 Framework ist ja bei Windows XP schon Standard. Ich wollte nur sehr ungern, dass man für ein kleines Tool extra noch ein .NET Framework installieren muss.

Grüße

Marco

3.971 Beiträge seit 2006
vor 15 Jahren

Es muss nicht zwingend Parallel Fx oder Parallel.For... sein. Für normale Multiprozessor-Anwendungen reicht die Verwendung der Klasse ThreadPool allemal aus. Die Verteilung der Threads wird anschließend von der CLR und dem Betriebssystem automatisch "korrekt" vorgenommen.

Parallel.Fx bringt nur was wenn es sich wirklich um Echtzeitsysteme handelt, wo jede MilliSekunde herausgeholt werden muss. Für Enduser reicht ThreadPool

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

998 Beiträge seit 2007
vor 15 Jahren

Entschuldigt wenn ich nochmal zum Verständins frage, aber ich bin grad etwas verwirrt, wenn ich Threads aus einem Threadpool nutze, werden die Threads automatisch auf die vorhandenen Cores verteilt?

Gruß David

2.082 Beiträge seit 2005
vor 15 Jahren

Hallo 1nf1n1ty,

ich würde das Ganze ebenfalls in einer Queue realisieren bzw. habe das schon intern für die Firma gemacht. 😁

Hmm... schade. Das 2.0 Framework ist ja bei Windows XP schon Standard. Ich hoffe du hast dich verschrieben und meinst Vista.

@DavidT: Ich glaube, dass mir da die Teammitglieder zustimmen, wenn ich sage, dass du deine Diskussion bitte in einen Extra-Thread packst.

Es ist toll jemand zu sein, der nichts von der persönlichen Meinung Anderer hält. - frisch-live.de

3.971 Beiträge seit 2006
vor 15 Jahren

@David T.

Die Verteilung der Threads wird anschließend von der CLR und dem Betriebssystem automatisch "korrekt" vorgenommen.

Die CLR/BS macht das für dich entsprechend deiner Hardware und Software-Konfiguration entsprechend richtig.

Ein Großer Vorteil von Parallel Fx ist, es verteilt die Tasks entsprechender korrekter auf den verfügbaren Threads. Es kann beispielsweise vorkommen, du hast noch 300 Aufgaben zu bearbeiten, 250 davon hat Thread1 und 50 Thread2. Parallel Fx kann das automatisch optimaler ausgleichen.

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...