Fdtd3d: Fragen zum parallelen Rechnen

Erstellt am 8. Jan. 2020  ·  9Kommentare  ·  Quelle: zer011b/fdtd3d

Hallo Gleb,

Ich bin Chengyi. Vielen Dank für die Entwicklung dieses großartigen Projekts. Es ist wirklich hilfreich, um FDTD und seine Parallelität zu studieren. Aber ich bin auf einige Probleme bei der Verwendung des MPI/GPU-Computing gestoßen.

  1. Das Problem ist, dass wenn ich den fdtd3d-Code mit dem folgenden Befehl aufrufe,
    ./Release/Source/fdtd3d --cmd-from-file ./Examples/vacuum3D_test.txt
    in dem ich "vacuum3D_test.txt" basierend auf der "vacuum3D.txt" erstellt habe, indem ich den folgenden Code eingefügt habe
--use-cuda
--cuda-buffer-size 1
--cuda-gpus 0
--num-cuda-threads-x 4
--num-cuda-threads-y 4
--num-cuda-threads-z 4

Das Programm zeigt nur das Protokoll "Loading command line from file ./Examples/vacuum3D_test.txt
" und warte weiter, bis ich es töte. Ich frage mich nur, ob es einige Konfigurationen gibt, die ich nicht richtig eingestellt habe?
Übrigens, das sind meine cmake-Flags, falls Sie es brauchen:
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DVALUE_TYPE=f -DPRINT_MESSAGE=ON -DCUDA_ENABLED=ON -DCUDA_ARCH_SM_TYPE=sm_60 -DCXX11_ENABLED=ON -DPARALLEL_GRID=ON -DPARALLEL_GRID_DIMENSION=3

  1. Auch wenn ich die "vacuum3D.txt" von MPI simuliert habe, ist die Skalierbarkeit von fdtd3d nicht sehr ideal. Zum Beispiel beträgt die Rastergröße 40 x 40 x 40, was 64000 entspricht. Und ich habe einen Chip mit 18 Kernen. Wenn es mit 1 Prozess geht, kostet es 67,74 Sekunden und es wird ungefähr 11,34 Sekunden dauern, wenn 8 Prozessoren aktiviert sind. Die Beschleunigung liegt bei etwa 6. Und wenn ich mehr Prozessoren wie 18 anwende, ist die Zeitreduzierung trivial, sagen wir von 11,34 s auf 9,6 s. Ist das vernünftig? Darf ich fragen, ob es Simulationskonfigurationen gibt, die die parallele Rechenleistung optimieren können?

Wenn Sie weitere Simulationsdetails benötigen, lassen Sie es mich bitte wissen. Vielen Dank.

Mit vielen Dank und Wünschen,
Tschengyi

Question

Alle 9 Kommentare

  1. Ich glaube nicht, dass es hängen bleibt, es führt nur Berechnungen durch, die sogar im RelWithDebInfo -Modus viel langsamer sind. Außerdem wird bei Cuda-Starts am Ende der Ausführung ein vollständiges Protokoll gedruckt.

Kleiner Tipp: Es ist schneller (in Bezug auf Kompilierung und Ausführung), -DSOLVER_DIM_MODES anzugeben, wenn Sie genau wissen, welche Modi Sie verwenden werden. Standardmäßig werden alle Modi in Binärdateien kompiliert, was die Kompilierungszeit im Falle von Cuda-Builds erheblich verlängert. In Ihrem Fall würden -DSOLVER_DIM_MODES=DIM3 ausreichen.

  1. Hier gibt es einiges zu beachten. Zunächst einmal ist die Gesamtausführungszeit jedes Zeitschritts die Summe aus Rechenzeit und Anteilszeit. Wenn das Grid relativ klein ist, wie in Ihrem Fall, kann die Freigabezeit erheblich sein und eine sorgfältige Auswahl der virtuellen Topologie ist erforderlich (fdtd3d zeigt die beste virtuelle Topologie für die angegebene Grid-Größe in seiner Ausgabe).

Auf Systemen mit gemeinsam genutztem Speicher sind jedoch überhaupt keine Operationen erforderlich (außer für die Thread-Synchronisation). Aus diesem Grund ist OpenMP hier viel besser geeignet als MPI, und MPI-basierte Programme zeigen nicht die beste Beschleunigung. Leider wird OpenMP in fdtd3d noch nicht unterstützt.

Vor diesem Hintergrund gibt es in fdtd3d noch Dinge zu optimieren.

  • Standardmäßig wird nur die Ox-Achse zwischen Berechnungsknoten verteilt, aber Sie können dies mit -DPARALLEL_BUFFER_DIMENSION=xyz ändern, wodurch das Raster zwischen Chunks in allen Dimensionen aufgeteilt wird. Überprüfen Sie die fdtd3d-Ausgabe, da sie die optimale virtuelle Topologie empfiehlt.
  • Die Größe des Puffers kann mit --buffer-size B eingerichtet werden, und der Share-Vorgang wird nur alle B Schritte durchgeführt. In diesem Fall ist die optimale virtuelle Topologie, die von fdtd3d empfohlen wird, nicht garantiert optimal. Sie können die virtuelle Topologie jedoch manuell mit --manual-topology --topology-sizex X --topology-sizey Y --topology-sizez Z festlegen.

Beachten Sie, dass, wenn die Anzahl der Prozesse kein Teiler der Gesamtgröße des Grids ist, die von fdtd3d empfohlene optimale virtuelle Topologie ebenfalls nicht garantiert optimal ist.

Vielen Dank für diese zeitnahe Antwort.

  1. Was das Single-GPU-Computing betrifft, habe ich fdtd3d mit den folgenden Flags neu erstellt

cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DVALUE_TYPE=f -DPRINT_MESSAGE=ON -DCUDA_ENABLED=ON -DCXX11_ENABLED=ON -DPARALLEL_GRID=ON -DPARALLEL_GRID_DIMENSION=3 -DSOLVER_DIM_MODES=DIM3 -DPARALLEL_BUFFER_DIMENSION=x

und es funktionierte in meiner Workstation. (Übrigens, meine Workstation hat vier Tesla P100, von denen der Bogen SM_60 sein sollte)

  1. Wenn ich das Multi-Gpu-Computing mit aktivieren möchte
    mpiexec --mca btl ^openib -n 2 ./Release/Source/fdtd3d --cmd-from-file ./Examples/vacuum3D_test.txt
    und die CUDA-cmds
--use-cuda
--cuda-buffer-size 2
--buffer-size 2
--cuda-gpus 0,1
--num-cuda-threads-x 4
--num-cuda-threads-y 4
--num-cuda-threads-z 4

Fehler tritt wie gezeigt auf:

Calculating time step 0...
Calculating time step 1...
Fatal error: an illegal memory access was encountered at /home/t00540502/fdtd3d/Source/Scheme/InternalScheme.inc.h:912
*** FAILED - ABORTING
-------------------------------------------------------
Primary job  terminated normally, but 1 process returned
a non-zero exit code.. Per user-direction, the job has been aborted.

Es scheint, dass der erste Schritt in Ordnung war, aber etwas stimmt nicht mit der Funktion InternalSchemeKernelHelpers::calculateFieldStepIterationKernel , die im zweiten Schritt aufgerufen wird. Ich frage mich, ob es einige Fehler geben muss, die ich bei der Verwendung von MPI + CUDA gemacht habe. Können Sie mir bitte beibringen, wie man es richtig nennt?
Vielen Dank.

Am besten

Vielleicht stimmt etwas mit sm_60 arch nicht, ich habe es nicht getestet. Der Standardbogen ist sm_20, also sollte es auf Ihren Karten funktionieren. Manchmal habe ich jedoch illegal memory access gesehen, als cuda arch nicht mit der Rechenleistung der GPU übereinstimmte.

Multi-GPU-Berechnungen haben eine begrenzte Anwendbarkeit. Wenn alle Daten in den Speicher einer einzelnen GPU passen, wäre es viel schneller, Berechnungen auf dieser einzelnen GPU auf einem einzelnen Rechenknoten durchzuführen (da es keine zwischenzeitliche Datenfreigabe zwischen CPU/GPU und zwischen verschiedenen Rechenknoten gibt).

Aber wenn Grids sehr groß sind und sich nicht im Speicher eines einzelnen Rechenknotens befinden können, gibt es keine andere Wahl, als mehrere Rechenknoten zu verwenden, von denen jeder möglicherweise eine GPU hat. In diesem Fall wird die CPU-GPU- und CPU-CPU-Datenfreigabe alle B Schritte durchgeführt, standardmäßig B=1 . Dies ist viel langsamer als einfache Berechnungen aller Zeitschritte auf einer einzelnen GPU.

Multi-GPU-Berechnungen werden in fdtd3d noch nicht vollständig unterstützt, da sich fdtd3d derzeit darauf verlässt, dass der Benutzer sicherstellt, dass alle Daten dort hinpassen, wo sie hinpassen (sowie im Nur-CPU-Modus). Mit solchen Einschränkungen sollte es also funktionieren.

@solotcy Es gab einen Fehler mit nicht gesetztem Bogen (siehe #140). Bitte erkundigen Sie sich bei sm_60 nach diesem PR.

Illegal memory access bezieht sich auf den Zugriff auf die globale Variable cudaSolverSettings, die sich im Gerätespeicher befindet (siehe INTERNAL_SCHEME_BASE<Type, TCoord, layout_type>::calculateFieldStepIteration ):

if (SOLVER_SETTINGS.getDoUseTFSF ())

Auf 2 von 3 GPUs mit der gleichen Rechenleistung sm_35, auf denen ich fdtd3d getestet habe, funktioniert alles einwandfrei (alle GPUs sind unterschiedliche Modelle). Bei einem wird cudaSolverSettings jedoch aus irgendeinem Grund NULL, wenn die Methode getDoUseTFSF eingegeben wird (dh dieser ptr ist NULL). Ich konnte nicht verstehen, warum dies passiert, aber nach meinen Erkenntnissen kann dies auf eine Fehlfunktion des Geräts zurückzuführen sein.

Es sieht so aus, als ob Sie fdtd3d zumindest auf einer Ihrer 4 GPUs erfolgreich starten konnten. Probieren Sie den Nur-GPU-Modus auf jeder GPU separat aus. Da alle Ihre 4 GPUs genau gleich sind, sollte es überhaupt keinen Unterschied im Verhalten von fdtd3d geben. Wenn es einen Unterschied gibt, wird die Ursache wahrscheinlicher, dass es sich um eine Fehlfunktion des Geräts handelt.

Vielen Dank für die Antworten.

Ich habe PR #140 überprüft und fdtd3d mit dem hinzugefügten Flag -DCUDA_ARCH_SM_TYPE=sm_60 neu erstellt. Leider tritt das gleiche Problem auf.

Wie Sie jedoch erwähnt haben, bin ich auf denselben Fehler gestoßen, als ich im Einzel-GPU-Modus zwischen verschiedenen GPUs gewechselt habe. Und es ist nicht der erste Schritt, sondern der zweite, wie zuvor,

Estimated current size: 1437644553 byte.
Setup blocks:
blockCount:
Coord (X : 1.000000, Y : 1.000000, Z : 1.000000).
blockSize:
Coord (X : 200.000000, Y : 200.000000, Z : 200.000000).
Calculating time step 0...
Calculating time step 1...
Fatal error: an illegal memory access was encountered at ~/fdtd3d/Source/Scheme/InternalScheme.inc.h:912

Und die Dinge werden irgendwie seltsam, da es nur bei der ersten GPU funktionierte. Bei den anderen drei schlug alles fehl und hatte die gleichen Fehlerinformationen.

Danke für deine Tests! Ich konnte endlich den Hauptgrund für dieses Problem herausfinden. PR #141 löst das Problem. Jetzt sollte fdtd3d auf allen Ihren GPUs funktionieren. Der Multi-GPU-Modus scheint jetzt auch zu funktionieren.

Danke für eure Antworten und den geänderten Code. Ich konnte das Programm auf meiner Workstation mit so vielen GPUs ausführen, wie ich möchte. Dann kann ich die Skalierbarkeit sowohl auf CPUs als auch auf GPUs testen.
Es ist ziemlich cool, danke!!!

Fühlen Sie sich frei, dieses Problem erneut zu öffnen, wenn Sie weitere Fragen haben.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

oy picture oy  ·  47Kommentare

franciscolourenco picture franciscolourenco  ·  15Kommentare

andersk picture andersk  ·  81Kommentare

gyullo picture gyullo  ·  33Kommentare

tekezo picture tekezo  ·  22Kommentare