Sollte ich Threading und Rekursion zusammen verwenden?

8

Ich habe schon eine Weile mit BSP-Bäumen herumgebastelt und spiele auch mit Threads. Beim Hinzufügen eines Dreiecks zu einer BSP-Struktur besteht die Möglichkeit, einen neuen Thread für die parallele Verarbeitung von Daten zu erstellen.

%Vor%

Die beiden obigen Einfügungsoperationen können von zwei Threads ausgeführt werden, und da sie nicht dieselben Daten modifizieren, kann eine billige Synchronisation verwendet werden.

%Vor%

Diese neue Methode versucht, einen Thread zu erstellen, um den Vorgang parallel abzuschließen, sollte aber nicht fehlschlagen, wenn der Thread nicht erstellt werden kann (er wird einfach zum ursprünglichen Algorithmus zurückkehren).

Ist das eine vernünftige Programmierung, oder verwende ich Threads nicht richtig? Ich habe keine Literatur zu dieser Technik gefunden. Ich mag es, dass es dazu tendiert, meine CPU voll auszunutzen (2 Kerne) und theoretisch auf eine beliebige Anzahl von Prozessoren skalieren würde. Ich mag es nicht, dass es auf CPU und Speicher schrecklich verschwenderisch ist.

    
Martin 03.10.2008, 13:59
quelle

3 Antworten

11

Threads sind großartig, wenn ein Teil der Verarbeitung auf etwas Externes wartet (Benutzereingabe, I / O, einige andere Verarbeitungen) - der Thread, der wartet, kann weiter warten, während ein Thread, der nicht wartet, weiter vorne schmiedet .

Bei prozessintensiven Aufgaben verursachen jedoch mehr Threads als Prozessoren tatsächlich Overhead. Es scheint so, als ob deine Threads alle "CPU-Arbeit" erledigen, also bleibe ich bei einem Thread pro Kern - Test, um die optimale Anzahl zu finden.

Der größte Overhead entsteht durch Kontextwechsel (Einfrieren eines Threads und Laden des Ausführungskontexts des nächsten) sowie Cache-Fehler, wenn Threads Aufgaben mit unterschiedlichem Speicher ausführen (wenn Ihr Thread den CPU-Cache effektiv nutzen kann) .

    
Philip Rieck 03.10.2008, 14:03
quelle
2

Am besten wäre es, einen Threadpool zu erstellen und ihn dann "transparent" zum Hinzufügen von Knoten zu verwenden.

Erstellen Sie zum Beispiel 2 Threads beim Programmstart, lassen Sie sie auf einen Semaphor oder ein Ereignis warten. Wenn Sie Knoten hinzufügen möchten, fügen Sie die Daten in eine Warteschlange ein und lösen dann den Semaphor aus. Dies weckt einen der Threads, der die Daten aus der Warteschlange löscht und die Verarbeitung durchführt. (Stellen Sie sicher, dass der Zugriff auf die Warteschlange threadsicher ist - am besten mit einem kritischen Abschnitt synchronisiert).

Die Gesamtleistung Ihrer App ist langsamer, da Sie mehr Aufwand haben, Daten in die Warteschlange zu kopieren und die zusätzlichen Threads auszuführen, aber wenn Sie früher auf einem einzelnen Kern ausgeführt haben, werden Sie jetzt auf 2 ausgeführt wenn die Threading-Verarbeitung teuer ist.

    
gbjbaanb 03.10.2008 14:29
quelle
0

Sicher, Quicksort kann z. B. sehr einfach Multithread-programmiert werden und erzielt einige große Leistungssteigerungen auf Multicore-Systemen und einige kleine Leistungsverluste auf Multithreading-Systemen. Denken Sie daran, dass Sie jetzt zweimal Overhead hinzufügen - einmal für den Stack, um die Rekursion zu speichern, und einmal für den Thread. Wenn Sie also eine große Anzahl von Rekursionen durchführen, kann ein System schneller überlastet werden als ein Ansatz ohne Multithreading.

    
tloach 03.10.2008 14:36
quelle

Tags und Links