Fragen zu Multithreding

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

Joel

Betreff: Fragen zu Multithreding

BeitragDo, März 22, 2012 19:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Da ich gerade einen kleinen Buddhabrot Renderer schreibe, und ich um ein schönes Bild zu Rendern 2h benötigte, dachte ich es könnte etwas schneller sein, das ganze mit Multithreading zu machen.

Kann ich eigentlich aus mehreren Threads in dasselbe Array schreiben?
Oder muss ich da irgendwas mit diesen Mutexen machen?

Danke schon mal für eure Hilfe!

M0rgenstern

BeitragDo, März 22, 2012 19:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Also bei Multithreading kannst du afaik nicht auf die gleiche Variable aus verschiedenen Threads zugreifen.
Beziehungseise, zugreifen geht schon, aber wenn du die Variable noch nicht richtig gespeichert hast, wird sie einfach mit dem neuen Wert überschrieben. Das kann Fehler verursachen.
Deshalb musst du Mutex nutzen.

Lg, M0rgenstern

Joel

BeitragDo, März 22, 2012 20:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Also mach ich einfach vorm schreiben LockMutex und nachher UnlockMutex, oder?

EDIT: Ja genau so gehts.. Danke
 

c64

BeitragSa, März 24, 2012 11:12
Antworten mit Zitat
Benutzer-Profile anzeigen
.... Ist eine möglichkeit, wenn nich sogar in diesem Fall die beste.

[EDIT]
So wie du es jetzt machst ist es doch auch Linear und nicht Paralell? Wenn ein Thread auf den anderen warten muss? (hehe jou sieht Noobody genauso Smile )
[/EDIT]



Allerdings wenn du ein Array/Bank/linearen Speicherbereich, hast was befüllt werden soll, wir gehen jetzt von größeren Datenmengen aus Wink.

Dann kannst du jeden Thread damit beauftragen nur bestimmte Bereiche des Arrays zu "berechnen"/"befüllen" was auch immer, vorausgesetzt die Berechnung kann unabhängig von den Teilbereichen durchgeführt werden .

Pseudocode !

Code: [AUSKLAPPEN]


Array[100];

Threads[10]

ArrSegements = sizeofArray (Array) / sizeofArray (Threads);

for (task =0; task<ArrSegements ; task++)  {

ArrOffset = task * ArrSegements

CalcSomething ( Threads[task], ArrOffset, ArrSegments, ... )

}



Hoffe is halbwegs verständlich anhand des Pseudocodes.

Bei großen (Datenmengen) Bildern würde dies gehen zum reinladen oder kopieren/verschieben, was auch immer. Keine Ahnung ob sich das so auch auf das Mandelbrot anwenden lässt. Wollte einfach nur mal diese Möglichkeit aufführen.


mfg. Patrick
Betreten verboten! Kinder haften für ihre Eltern!
  • Zuletzt bearbeitet von c64 am Sa, März 24, 2012 12:26, insgesamt 2-mal bearbeitet

Noobody

BeitragSa, März 24, 2012 11:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Pro Arrayzugriff einen Mutex locken und nacher wieder unlocken ist extrem langsam, da Mutexe einen nicht zu unterschätzenden Overhead haben - vor allem, wenn man den Aufwand eines Mutex.Lock mit der Arbeit vergleicht, die du während eines Locks machst (beim Buddhabrot inkrementierst du ja nur einen Zähler im Array).
Zudem hast du vermutlich einfach einen Mutex für das ganze Array, was dazu führt, dass zu jedem Zeitpunkt immer nur ein Thread das Array benutzen kann. Da aber jeder Thread für jeden iterierten Punkt das Array benötigt, kreisen sie alle im kritischen Codeblock und warten auf den Mutex.Lock, was dann dazu führt, dass du im Prinzip wieder ein Singlethread-Programm hast, da zu jedem Zeitpunkt immer nur ein Thread Fortschritt macht.

Ich wäre also nicht erstaunt, wenn deine Multithreaded-Lösung langsamer ist als der ursprüngliche Code.

Leider sind die Pfade der einzelnen Punkte im Mandelbrot durch das Array nicht vorhersehbar, daher kann man also nicht einfach die Arbeit so auf einzelne Threads aufteilen, dass sie keine Daten untereinander teilen.

In diesem Fall müsste man daher kompliziertere Methoden anwenden, um den Code mit mehreren Threads schnell zu machen - aber du hast Glück! Da du im Buddhabrot ja wirklich nur einzelne Stellen in einem Array hochzählst, kannst du die BMax-Funktion AtomicAdd benutzen. Diese holt sich einen Wert aus dem Speicher, addiert den angegebenen Wert und schreibt den Wert zurück, und das ganze atomic, d.h. kein anderer Thread kann während der Operation einen inkonsistenten Wert lesen oder schreiben.

Statt Iterations[PointX, PointY] :+ 1 (oder wie dein Code halt so aussieht) schreibst du also einfach ein AtomicAdd(Iterations[PointX, PointY], 1) und deine Multithread-Lösung ist fertig - ganz ohne langsame Mutexe und komplizierten Code Razz
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

Joel

BeitragSa, März 24, 2012 21:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Es war zwar mit Mutexn auch schon schneller, aber mit AtomicAdd nochmal etwas.

Danke Laughing

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group