Welche Operation im Programm dauert immer länger



  • Hallo zusammen,

    mir fällt schon der Titel schwer zu formulieren aber es interessiert mich so sehr, dass ich mich bei euch jetzt einfach mal informieren möchte, weil von der offiziellen Seite kein Statement kommt. Okay. Ich arbeit mit OpenFOAM, das ist eine Open Source Toolbox um Simulationen mittels der Finiten Volumen Methode durchzuführen. Ich hab aber seit der letzten Woche etwas entdeckt, dass sehr merkwürdig ist.

    Was wird gemacht:

    - a) Ich gehe in den nächsten Zeitschritt
    - b) Ich baue mir ein Matrixsystem
    - c) Ich löse diese Matrix mittels einem linearen Löser (Preconditioned Conjugated Gradient)
    - d) Mit den neuen Werten wird b) und c) wiederholt
    - e) Wenn konvergiert, geh zum nächsten Zeitschritt

    Normalerweise wird das b) - c) ca. 1 - 20 mal gemacht. Danach ist normalerweise das System gelöst. Allerdings bewege ich mich in einem etwas anderen Feld als der Strömungsmechanik -> Spannungsberechnung mittels der FVM. Über diverse Paper und Dissertationen weiß ich, dass b) und c) mehrere Tausend mal gemacht werden müssen damit alles konvergiert. Manchmal sogar bis 100.000x. Das ist eigentlich kein Problem, wenn ich diese Merkwürdikeit nicht hätte.

    Kommen wir nun zu dem was ich gerne wissen würde. Wenn ich die Schritte b) und c) etliche male durchführe, dann passiert folgendes. Für das Lösen des Gleichungssystems für die ersten bspw. 50 b) c) loops benötige ich 11ms. Ich habe nach jedem Loop eine Bessere Lösung und gehe davon aus das das weitere Lösen wesentlich leichter geht und weniger innere Iterationen (die vom PCG) benötigt. Allerdings passiert folgendes: Wenn ich mir die Zeit für die Berechnung von 50 b) c) Loops ausgebe, stelle ich fest, dass sich die Zeit linear vergrößert. Heißt also, die ersten 50 brauchen bspw. 11ms und die gleichen 50 Loops nach 5000 dieser b) c) Loops brauchen auf einmal 6-8s (also ein deutlicher Anstieg). Das der Löser mehr innere Iterationen macht kann nicht sein, weil ich die auf 30 Limitiert hab und ich die bereits am Anfang erreiche.

    Es gibt also irgendwo im Code eine Stelle die auf irgendwelche Art und Weise immer länger und länger braucht und ich würde gerne wissen welche Operation das ist.

    Ich weiß das diese Zeile

    DEqn.solve();
    

    der Bösewicht ist. Allerdings versteckt sich ja dahinter einiges mehr als nur ein paar Code Zeilen. So und nun meine Frage. Ist es irgendwie möglich herauszufinden, welche Operation bei dem Aufruf dieser Funktion, Zeitlich länger und länger braucht? Es ist nämlich nicht so das die Zeit minimal ansteigt sonder extrem (wie oben schon beschrieben). Der lineare Anstieg hier führt natürlich zu einem parabolischen Verhalten für die Lösung des Systems.

    Lustig ist auch, dass wenn ich nach bspw. 1000 b) c) loops in den nächsten Zeitschritt wechsel, die b) c) Loops wieder runter rattern wie die Katz.

    Ich frage jetzt hier nicht nach dem Problem sondern welche Möglichkeiten ich habe die Stelle herauszufinden die da länger und länger benötigt.

    Was ich versucht hab:

    - Starte den Löser und setz ihn in den Hintergrund
    - Warte einige Zeit bis ich 10.000 b) c) Loops hinter mir hab und ich deutlich merke das alles langsamer wird
    - PID des Prozesses ermitteln
    - GDB Starten mit der PID:

    gdb application PID
    

    Ich kann dann zwar überall hin, bzw. sehen in welche Funktionen etc. ich geh aber ich hab da natürlich zeitlich keine Analysemöglichkeit, oder gibt es da was spezielles?

    Ich hoff ich hab mich deutlich Ausgedrückt.
    Bin mal interessiert ob es Programme gibt, die das ermitteln können oder wie man da im Allgemeinen vorgeht.

    Viele Grüße
    Tobi



  • Du suchst einen Profiler, z.B. perf oder gprof.



  • Hallo Manni,

    das hört sich ja schon mal ganz gut an was ich da gelesen habe. Soweit ich das jetzt verstanden hab, muss ich lediglich meinen Code neu Kompilieren (Flag: -pg) und danach start ich einfach mein Programm wie gewohnt und erhalte dann eine gmon.out Datei. Dannach ruf ich gprof mit meinem Programm und der gmon.out Datei auf und erhalte dann Informationen über das Programm.

    Ich werde das mal testen. Danke schonmal für die Info. Hört sich aufjedenfall so an als würde es das sein was ich suche. Danke dir.



  • Ich kann noch Intel VTune empfehlen, allerdings kostet das ne Kleinigkeit. Aber vielleicht gibts da ne kostenlose Testversion.

    Ist halt grafisch und GUI, was es einfacher macht in meinen Augen.



  • Hallo zusammen,

    ich habs mal mit gprof durchgecheckt. Gehe ich da richtig der Annahme, dass das Flat Profile mir bpsw. angibt welche Funktion am längsten dauert. Im Vorliegenden Fall wäre das

    Flat profile:
    
    Each sample counts as 0.01 seconds.
      %   cumulative   self              self     total           
     time   seconds   seconds    calls  ms/call  ms/call  name    
     21.20      2.26     2.26    10010     0.23     0.23  Foam::List<Foam::token>::~List()
     15.67      3.93     1.67    30028     0.06     0.06  Foam::List<Foam::SolverPerformance<Foam::Vector<double> > >::setSize(int)
      5.68      4.54     0.61 100212802     0.00     0.00  Foam::Ostream& Foam::operator<< <Foam::Vector<double>, double, (unsigned char)3>(Foam::Ostream&, Foam::VectorSpace<Foam::Vector<double>, double, (unsigned char)3> const&)
      5.25      5.10     0.56 50105055     0.00     0.00  Foam::Ostream& Foam::operator<< <Foam::Vector<double> >(Foam::Ostream&, Foam::SolverPerformance<Foam::Vector<double> > const&)
      4.88      5.62     0.52    10010     0.05     0.05  Foam::List<Foam::SolverPerformance<Foam::Vector<double> > >::~List()
    

    Würde ja bedeuten, dass der Destruktor ::~List() am längsten braucht. Der wurde auch 10010x aufgerufen, das genau der Anzahl an Iterationen entsprecht. Der zweite mit 30028 calls wäre auch gut weil ich in x, y, z Löse, warum ich da aber 2 weniger hab ist mir nicht klar. Egal.

    Ich hab gerade nochmals einen weitern Test am Laufen bei dem ich 20.000 Iterationen mache. Mal schaun was rauskommt.

    Definitiv interessant. Muss mich noch weiter mit dem gprof auseinandersetzen, damit ich das richtig interpretiere.



  • Hallo zusammen,

    ich wollte mich nochmals für die Programme bedanken. gprof ist echt eine Hilfe. Hab jetzt die entsprechende Funktion gefunden und muss mal schauen was die gezielt macht.

    Nachdem ich mich gestern dann noch ein bisschen über den gprof belesen habe muss ich sagen, super Tool. Wieder was gelernt.

    Grüße Tobi


Log in to reply