Fragen zu Multithreding
Übersicht

![]() |
JoelBetreff: Fragen zu Multithreding |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Also mach ich einfach vorm schreiben LockMutex und nachher UnlockMutex, oder?
EDIT: Ja genau so gehts.. Danke |
||
c64 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
.... 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 ![]() [/EDIT] Allerdings wenn du ein Array/Bank/linearen Speicherbereich, hast was befüllt werden soll, wir gehen jetzt von größeren Datenmengen aus ![]() 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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 ![]() |
||
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Es war zwar mit Mutexn auch schon schneller, aber mit AtomicAdd nochmal etwas.
Danke ![]() |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group