PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Multithreading in Molekulardynamik-Simulationen?


Arokh
2007-08-26, 01:11:01
Hi Leute,

angespornt durch diesen Thread:

http://www.forum-3dcenter.org/vbulletin/showthread.php?t=376701&highlight=Molekulardynamik

habe ich mich mal mit der Frage beschäftigt, wie gut sich Molekulardynamik-Simulationen in Form von Multithreading parallelisieren lassen. Ich habe z.B. mal vor einer Weile eine Simulation von wechelwirkenden Teilchen geschrieben, und habe jetzt, wo ich gerade einen neuen Dual Core-Prozessor habe, darüber nachgedacht, diese durch Multithreading zu beschleunigen. Dabei bin ich aber auf das Problem gestoßen, daß die Wechselwirkung zwischen den Teilchen die Parallelisierbarkeit massiv einschränkt:

N Teilchen werden durch einen Positionsvektor im 6*N-dimensionalen Phasenraum (für jedes Teilchen 3 Ortskoordinaten und 3 Geschwindigkeitskomponenten) beschrieben. In jedem Rechenschritt wird aus dem aktuellen Positionsvektor ein Vektor mit den Zeitableitungen berechnet und daraus der Positionsvektor für den nächsten Zeitpunkt. Eine naheligende Idee wäre jetzt, zwei Threads zu machen, von denen jeder N/2 Teilchen berechnet. Das Problem dabei ist aber, daß aufgrund der Wechselwirkung die Zeitableitung für jedes Teilchen i.a. von den Positionen aller N Teilchen abhängt. D.h. man kann nicht einfach den Zeitableitungsvektor der ersten N/2 Teilchen unabhängig vom Positionsvektor der übrigen N/2 Teilchen berechnen. Vielmehr müßte, wenn die Zeitableitungen der ersten N/2 Teilchen zum i-ten Zeitpunkt berechnet werden, sichergestellt sein, daß von den übrigen N/2 Teilchen die entsprechenden Positionen zum i-ten Zeitpunkt bereits berechnet sind.

In einer Multithreading-Realisierung würde das einen enormen Synchronisationsaufwand zwischen den beiden Threads bedeuten: wenn ein Thread die Zeitableitungen seiner N/2 Teilchen zum Zeitpunkt i berechnen will, muß er erst überprüfen, ob der andere Thread die Positionen seiner Teilchen für den Zeitpunkt i fertig hat, und gegebenenfalls darauf warten. Ich habe das mal tatsächlich ausprobiert, und es sieht so aus, daß der Synchronisationsaufwand so sehr auf die Performance drückt, daß diese unter das Niveau der Singlethreading-Lösung fällt.

Daher wollte ich mal nachfragen, ob es da vielleicht ein paar Tricks gibt, die man verwenden kann. Laut o.g. Thread scheint Parallelisierung bei Molekulardynamik-Simulationen ja durchaus ein Thema zu sein.

Ihm
2007-08-26, 02:02:38
Ganz im Ernst:
Hol dir eine G80er Karte, zieh dir CUDA und leg los.
Da alles in C ist, ist die Integrierung nicht schwer.
Für einen guten Einstieg: http://forums.nvidia.com/

Zu MDS lies dir das mal durch:
http://portal.acm.org/citation.cfm?id=1224606

Coda
2007-08-26, 02:04:41
Thema verfehlt? :|
Ihm ging's prinzipiell darum wie man es überhaupt parallelisieren kann. Das muss man auch auf G80.

del_4901
2007-08-26, 02:31:38
@Arokh: kannst du das nicht Pipelinen? Sprich CPU0 berechnet Zeitschritt t und CPU1 den Zeitschritt t+1?

Ihm
2007-08-26, 03:00:16
Thema verfehlt? :|
Ihm ging's prinzipiell darum wie man es überhaupt parallelisieren kann. Das muss man auch auf G80.

Jo, stimmt. Hab ich verpeilt. :D

Stone2001
2007-08-26, 11:39:07
@Arokh: kannst du das nicht Pipelinen? Sprich CPU0 berechnet Zeitschritt t und CPU1 den Zeitschritt t+1?
Ist hier nicht möglich (leider ist es das nur in den seltesten Fällen), da der Schritt t+1 von Schritt t abhängt.

Die Parallelisierungsmethode, die du vorgeschlagen hast, sollte eigentlich funktionieren. Da du ein Shared-Memory-System hast, kannst du einfach deine Teilchenmenge in 2 Teile aufteilen. Auf diesen Hälften kannst du die Berechnung unabhängig voneinander durchführen (durch das Shared-Memory-System kannst du weiterhin auf alle Daten für die Berechnungen zugreifen).
Nach jedem Schritt wird durch eine Barriere sichergestellt, dass die beiden Teile nicht aus dem Ruder laufen. (In OpenMP dürfte das Ganze recht einfach zu realisieren sein)

Man bekommt dadruch zwar einen gewissen Synchronisationsoverhead, der sollte aber hier im Vergleich zu den Berechnungen vernachlässigbar sein. (anderenfalls einfach noch ein paar Teilchen hinzufügen)

Eine Parallelisierung mittels MPI stelle ich mir dagegen schon etwas schwieriger vor. Hier würde ich Clustern und mehrere Teilchen zu einem Markoteilchen verschmelzen, dadurch reduziere ich den Kommunikaitonsaufwand, bekomme aber ungenaue Ergebnisse.

MrMostar
2007-08-26, 12:52:34
Und wenn du jedem Teilchen einen eigenen Thread verpasst?
Nach einem Simulationsschritt müssen alle Threads synchronisieren, dann kann der nächste Schrit ablaufen.
geht zwar einiges für die Synch. verloren aber das wird durch die Skalierung wieder aufgewogen, besonders bei vielen Cores.

Trap
2007-08-26, 17:47:25
Ich habe das mal tatsächlich ausprobiert, und es sieht so aus, daß der Synchronisationsaufwand so sehr auf die Performance drückt, daß diese unter das Niveau der Singlethreading-Lösung fällt.
Wenn eine einzige Barrier pro Zeitschritt mehr Aufwand ist als die Hälfte der Teilchen mit einer CPU zu berechnen, hast du entweder sehr wenig Teilchen oder die Barriere sehr ineffizient implementiert.

Arokh
2007-08-26, 18:19:22
Es scheint an was anderem zu liegen. Ich habe mal testweise die Synchronisation komplett abgeschaltet, und die Performance ist immer noch so niedrig.

Arokh
2007-08-26, 18:28:22
@Arokh: kannst du das nicht Pipelinen? Sprich CPU0 berechnet Zeitschritt t und CPU1 den Zeitschritt t+1?die Parallelisierung zweier Zeitschritte geht nicht, weil das Resultat des ersten Zeitschritts die Grundlage für den zweiten ist.
Ich glaube auch nicht, daß das ein Pipeline wäre: Pipelining heißt, daß es mehrere Datensätze gibt, und mit der Bearbeitung des einen Satzes begonnen wird, während die des anderen noch läuft. In meinem Fall gibt es aber nur einen einzigen Datensatz.

Stone2001
2007-08-26, 19:05:58
Es scheint an was anderem zu liegen. Ich habe mal testweise die Synchronisation komplett abgeschaltet, und die Performance ist immer noch so niedrig.
Wie groß ist denn der Performanceunterschied zwischen Single- und Multicore?

Jetzt ohne dein Programm, deine Parallelisierungsmethode, deine Architektur zu kennen, würde ich mal tippen, dass du ein Bandbreitenproblem hast.

Rechne mal aus: Anzahl Teilchen * Anzahl Teilchen -1 * Größe der Datenstruktur pro Teilchen in Bytes * Iterationen pro Sekunde. (Iterationen pro Sekunden musst du halt messen, bei der Datenstruktur mußt du nur die Daten berücksichten, die auch wirklich für die Berechnung benötigt werden)

Passen alle Teilchen in den Cache? Oder liegen Teile davon im Hauptspeicher?