n-Body Simulation -> 64-Bit-Assembler + MultiThread + AssembleIt2() Update Benchmark

  • // EDIT Vielen Dank an die Tester eukalyptus, UEZ und die vielen anderen, die ich mit meinen PN´s nerven, und auf deren Rechnern ich meine Programme testen darf :thumbup:

    Hi,

    hier gibts einiges zur n-Body-Simulation zu lesen.
    Ich hab mich mal dran gemacht, den "inner loop" in 64-Bit-Assembler zu schreiben, und weil ich schon dabei war, gabs Multithreading noch dazu^^

    Das folgende Script läuft nur unter 64Bit-Betriebssystemen!
    Für die "Bastler" ist noch eine neue (Vorab-) Version von AssembleIt() angehängt. In dieser ist jetzt die FASM.dll im Script enthalten und wird direkt in den Speicher geladen (keine dll-Datei). Auf die FASM-UDF und Memory.UDF wird also völlig verzichtet :rock:
    Weiterhin wurde das "inlinen" noch weiter vereinfacht, der Assemblercode wird einfach zwischen #cs und #ce geschrieben.
    Bei Syntaxfehlern im Assemblercode springt der Cursor in Scite in die betreffende Zeile!

    Einen kleinen Wermutstropfen gibt es aber....die FASM.dll ist nur in 32-Bit verfügbar. Sie kann zwar anstandslos 64-Bit-Code assemblieren, aber nur aus einer 32Bit-Umgebung gestartet werden.
    Dazu habe ich mir folgenden Workaround überlegt:
    Erst per

    [autoit]

    #AutoIt3Wrapper_UseX64=n

    [/autoit]

    den Code assemblieren und dann einfach mit

    [autoit]

    #AutoIt3Wrapper_UseX64=y

    [/autoit]

    ausführen^^
    Beim Assemblieren wird dann bspw. eine Datei mit dem Binärcode angelegt, die dann eingelesen werden kann, alternativ könnte man auch direkt in die Scriptdatei schreiben...

    Vorteil bei 64Bit ist einfach die UNMENGE an verfügbaren Prozessorregistern. In der n-Body-Simulation gibt es nur noch Schreib- und Lesezugriffe in den Speicher um die Koordinaten einzutragen. Die gesamte Schwerkraft-Berechnung läuft in einer Handvoll Takte in den Prozessor-Registern ab!
    Da auch die 128-Bit SSE-Register verwendet werden, kann man die Interaktionen von 4 Körpern gleichzeitig berechnen.
    Um bei den heute vorhandenen Multi-Cores das letzte an Power rauszuholen, habe ich auch noch Multithreading integriert. Das war wesentlich einfacher, als ich gedacht hatte... 8o

    Wer also "FETTE" Prozessoren hat, der sollte mal schauen, was so geht....mein AMD A6-3400M (Laptop 4-cores @2400Mhz) schafft bei 30000 Partikeln 9.8e009 Interaktionen/Sekunde und 8 Takte/Interaktion, OHNE AVX, das 8 Körper gleichzeitig berechnet!
    Mal zum Vergleich, ein XEON-Phi 5110P mit 61 physischen Kernen schafft bei 24400 Partikeln "NUR" 54e009 Interaktionen/Sekunde (gleicher Algorithmus, beste Optimierung INTEL-Compiler! ). Bei 15x mehr Prozessoren also nur 5x mehr Leistung....LÄCHERLICH!!! :rofl:
    Eine Tesla K20x liefert in etwa 80e009 Interaktionen/Sec. bei 24400 Partikeln, bei einer Million Partikeln (lmaa) ca. 120e009 Interaktionen/Sec, DAS ist Power 8o

    Genaueres zum Thema gibt es HIER (sehr lesenswert!!!)

    Wer einmal assembliert hat, kann die ersten 325 Scriptzeilen weglassen^^ //EDIT oder gleich die Version "ohne ASM-Code und AssembleIt" starten
    VIEL SPASS!
    .....und schaut, ob eure Lüfter alle drehen....

    -Update 06.07.2013
    Rotation hinzugefügt, Anzeige verbessert
    -Update 07.07.2013
    Performance-Counter angepasst, RDTSC muss bei mehreren Threads durch CPUID serialisiert werden ! Thx an eukalyptus fürs testen!
    GUI angepasst, um die Titelleiste des Fensters im Sichtbereich zu halten
    -Update 13.07.2013
    Assembler-Code angepasst von 1/sqrt() ^4 zu 1 / sqrt() ^3 (Thx an eukalyptus), beeinflusst die Benchmarkergebnisse nicht.
    Vergleichbare Berechnungsschritte pro Sekunde zum Benchmark hinzugefügt
    Setzen der Prozessorflags FTZ Flush To Zero und DAZ Denormals Are Zero, um auch bei unterschiedlichen Betriebssystemen gleiche Startparameter für das Behandeln von Floating-Point-Exceptions zu erhalten.

    autoit.de/wcf/attachment/22322/
    autoit.de/wcf/attachment/21992/
    autoit.de/wcf/attachment/22327/ Benchmark

    Als grafisches Gimmick habe ich zwei "Galaxien" kollidieren lassen:
    autoit.de/wcf/attachment/22007/autoit.de/wcf/attachment/22087/

    Benchmarkergebnisse:

    Spoiler anzeigen

    Benchmark n-Body-Simulation

    Number Particles: 30000
    Processor: AMD A6-3400M APU with Radeon(tm) HD Graphics
    Number Processors(Cores): 4
    Number Threads: 4
    Overall Time: 73.81 Seconds
    Number Loops benchmarked: 113

    Average Interacts/sec: 5.80e+009
    Maximum Interacts/sec: 6.20e+009

    Average Steps/sec: 1.60
    Maximum Steps/sec: 1.72

    Average Ticks/Interact: 14.71 CAUTION! Depends on real Clockticks!
    Minimum Ticks/Interact: 14.36 CAUTION! Depends on real Clockticks!

    Average Clockticks[Mhz]: 1400 CAUTION! Clockticks may NOT match if over/underclocked! Please insert the real Clockticks!
    Maximum Clockticks[Mhz]: 1400 CAUTION! Clockticks may NOT match if over/underclocked! Please insert the real Clockticks!

    Average Looptime: 627.44 Milliseconds
    Fastest Looptime: 580.69 Milliseconds

    Spoiler anzeigen

    Benchmark n-Body-Simulation

    Number Particles: 30000
    Processor: AMD A6-3400M APU with Radeon(tm) HD Graphics
    Number Processors(Cores): 4
    Number Threads: 4
    Overall Time: 45.73 Seconds
    Number Loops benchmarked: 97

    Average Interacts/sec: 8.11e+009
    Maximum Interacts/sec: 9.97e+009

    Average Steps/sec: 2.23
    Maximum Steps/sec: 2.77

    Average Ticks/Interact: 9.56 CAUTION! Depends on real Clockticks!
    Minimum Ticks/Interact: 8.89 CAUTION! Depends on real Clockticks!

    Average Clockticks[Mhz]: 2300 Clockticks K10stat
    Maximum Clockticks[Mhz]: 2300

    Average Looptime: 451.31 Milliseconds
    Fastest Looptime: 361.01 Milliseconds

  • Schönes Stück Arbeit Andy :thumbup:

    Jetzt müssen wir "nur" noch ASM lernen, um brotlose Kunst zu erschaffen. Motivation und Ideen gibt es ja genug -> AAAMMMMIIIIIGGGAAAA :rock:

    Ich habe bald 4 Wochen Urlaub. Mal sehen, ob ich alter Sack was mit ASM hinbekommen kann.


    Danke für's "Sharen".


    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Hi,

    Zitat

    Leider entäuscht mein Laptop bei der Performance:
    3.2e009 Interaktionen/Sekunde und 49 Takte/Interaktion
    Intel Core i7-2640M

    Bei wievielen Partikeln?
    Spiel mal mit der Anzahl der Threads, ich vermute stark, dass sich der Turbo-Modus nur bei einem oder zwei belasteten Cores einschaltet.
    Auf der anderen Seite könntest du mal 4 oder 8 Threads testen, Intel unterstützt Hyperthreading.
    Weiterhin spielt sicherlich die Cache-Größe eine Rolle...

    Was mich auf die Idee bringt, eine Testsuite (Benchmark) zu schreiben 8o

  • Update:
    -Code aufgehübscht und angepasst
    -die beiden "Wolken" haben nun jeweils einen eigenen Farbton
    -Version ohne ASM-Code und AssembleIt() angefügt

    ToDo:
    Kollision zweier rotierender Spiralarm-"Galaxien", so wie HIER gezeigt^^
    Die Mechanik (also die Berechnung durch den ASM-Code) bleibt dabei bestehen, lediglich die Anfangsparameter (Geschwindigkeiten der einzelnen Partikel) müssen angepasst werden.
    Wer da physikalisch bissl fit ist, kann gerne einen Beitrag verfassen!
    Zzt. ist die Geschwindigkeit der Partikel beim Start des Scripts Null. Zuerst könnte man mal ausprobieren, beim Erstellen der "Wolke" jedem Partikel eine Geschwindigkeit tangential zum Wolkenmittelpunkt mitzugeben, dann sollten sich, je nach Geschwindigkeit, die Spiralarme ausbilden...

  • Update:
    - Rotation der "Galaxien" hinzugefügt, Rotationsgeschwindigkeit anpassbar
    - Anzeige verbessert, Partikel, die den Bildschirmbereich verlassen, werden nicht mehr "auf der anderen Seite" angezeigt

    Wer hat einen Quadcore mit Hyperthreading (8 Threads möglich! ) und würde einen Screen bzw. Ergebnisse mit Angabe des Prozessors posten?
    Jemand einen Bulldozer/Piledriver am Start?

  • Bei mir stürzt das Programm beim Starten sofort ab. Ich hatte erst den Verdacht, dass da irgendwo ein Befehl verwendet wird, der zu neu für meinen Prozessor (Intel Core 2 Quad Q8200) ist, aber ich habe keinen gefunden.



    Um bei den heute vorhandenen Multi-Cores das letzte an Power rauszuholen, habe ich auch noch Multithreading integriert. Das war wesentlich einfacher, als ich gedacht hatte... 8o


    Multithreading ist für solche Berechnungen auch sehr einfach und effektiv. Wirklich kompliziert wird es aber, wenn man mehrere Threads mit unterschiedlichen Aufgaben hat. Zur Zeit machst du es auch so, dass du jeden Frame neue Threads erstellst, dabei geht natürlich auch Zeit verloren. Dann kannst du in der Schleife, die wartet, bis alle Threads beendet haben, auch noch Sleep(0) einbauen, denn dadurch gibst du anderen Threads die Chance zur Ausführung.

  • Hi,

    Zitat

    Bei mir stürzt das Programm beim Starten sofort ab. Ich hatte erst den Verdacht, dass da irgendwo ein Befehl verwendet wird, der zu neu für meinen Prozessor (Intel Core 2 Quad Q8200) ist, aber ich habe keinen gefunden.

    Danke für die Rückmeldung!
    Ich verwende die AMD64 Architecture Programmers Manuals in der Revision 3.10 26568also die "alte" Version, die um Längen verständlicher und besser geschrieben und bebildert ist wie der DRECK, den man heute als Manual von den AMD-Seiten laden kann...
    Ich oute mich mal als AMD-Fanboy (hatte es schon immer mit den Underdogs^^^) aber was AMD mit den "neuen" Manuals den Leuten zumutet, ist gelinde gesagt eine Frechheit!

    Das Manual ist von 2007, also SSE, SSE2 und SSE3-Befehle sind implementiert, also nichts was ein "neuer" Prozessor nicht können könnte.

    Leider gibt es keine kostenlosen 64-Bit-Debugger, die wie bspw. Olly oder IDA Pro im 32-Bit-Modus beim Absturz die Fehlerstelle anzeigen, wenn doch jemand eine Info oder einen Link hat, bitte Posten!

    Schalte mal testweise DEP aus.

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    Einmal editiert, zuletzt von Andy (6. Juli 2013 um 21:14)

  • Bei meinem kleinen Rechner (Intel Atom 330) läuft das Programm nicht. (Absturz nach ca. 2sek, Fenster geht zu, Windows Errormeldung)
    Auf meinem Großen konnte ich es noch nicht testen.

    lg
    Mars

  • Oha, da habe ich wohl eine der Zwischenversionen vergessen upzudaten...
    Das Script stürzt ab, weil der ASM-Code nicht assembliert und in die Dateien geschrieben wurde...werde das im nnächsten Update fixen.

    In der Version ohne integrierten Assembler sollte es aber laufen!

  • Neue Versionen online, fangen nun ab, wenn vor dem Start nicht assembliert wurde.

  • Hi Andy,

    kannst du nicht ein Benchmark Mode einbauen, so dass das Ergebnis in einer Datei landet?

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Klar, mache ich...

    Dann werde ich aber auch auf deine Funktionen zur Ermittlung des genauen Prozessortaktes zurückgreifen müssen. RDTSC ist bei den neueren Prozessoren nämlich ABHÄNGIG vom Takt!
    Es ist definitiv nicht (mehr) so, dass die Time-Stamp-Counter bei jedem Takt um eins erhöht werden, vielmehr ist noch ein Teiler eingebaut, der abhängig vom Bustakt ist!
    Wieder ein eingebauter Stolperstein, um zu verschleiern, dass die neuen Prozessoren keinen Deut besser sind, als die "alten"!

  • Marthog,

    Zitat

    Zur Zeit machst du es auch so, dass du jeden Frame neue Threads erstellst, dabei geht natürlich auch Zeit verloren. Dann kannst du in der Schleife, die wartet, bis alle Threads beendet haben, auch noch Sleep(0) einbauen, denn dadurch gibst du anderen Threads die Chance zur Ausführung.

    Da hast du sicherlich Recht.
    Ich habe testweise

    [autoit]

    Until $flag = 1 and sleep(10)

    [/autoit]

    eingebaut, aber bei kleinen Anzahlen Partikeln (<10000) bietet der Schleifenoverhead von Autoit genug Zeit zum Interrupten, und bei Partikelanzahlen von >30000 und allen Cores unter Volldampf habe ich, egal, welche Sleeps eingestellt sind, Mausruckler und Unterbrechungen beim bspw. Fensterschieben. Was aber auch an meiner schwachbrüstigen CPU liegen kann.
    Ausserdem möchte ich ja sehen, was der Prozessor macht, wenn er nicht in jeder Millisekunde 50x in den tiefschlaf fällt 8o

    Eine weitere Möglichkeit wäre, sofort nach Beenden eines Threads einen neuen anzuwerfen und die Anzeige alle 50ms aufzurufen, schaumamal was das bringt

  • Hier meine Benchmark Werte:

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Hier meine Werte:

    Bei einem älteren Laptop stürzt das Script ab, ich habe aber den Übeltäter gefunden:
    Wenn ich rdtscp herausnehme, dann läuft das Script - allerdings ohne Benchmark.

    E

  • Hi,

    Zitat

    Wenn ich rdtscp herausnehme, dann läuft das Script - allerdings ohne Benchmark.

    Vielen Dank für diese Info!
    Warum und wieso das so ist, kann ich allerdings nicht nachvollziehen.
    Ich meine irgendwo gelesen zu haben, dass Windows die Benutzung der TSC Time-Stamp_Counter einschränken kann. Also sollte man das auch irgendwo "freischalten" können, ggf. hängt das hiermit zusammen.
    Die Performance-Counter sind bei mir (Win7-64) soweit ich das sehe, freigeschaltet. Eingabeaufforderung: perfmon

    // EDIT stürzt das Script bei der Verwendung von nur einem Thread auch ab?
    // EDIT2 RDTSC muss bei mehreren Threads serialisiert werden, neue Version in Post #1, bitte mal neu benchmarken und die neuen Ergebnisse mit den alten vergleichen, gibt es Unterschiede?

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    3 Mal editiert, zuletzt von Andy (7. Juli 2013 um 10:01)

  • Die Unterschiede zum Alten sind marginal:

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    Einmal editiert, zuletzt von UEZ (7. Juli 2013 um 11:45)

  • Er feuert leider nicht in den Turbo-Mode. ^^