Wie groß ist das Universum in KSP und wo ist das Ende?

  • Wenn du jetzt dann mit der Genauigkeit von double rechnen willst, dann wird aus 1 = 100.000.000.000.000.000.
    Kerbin hat dann eine Apoapisis von 1.359.984.025.600.000.000.000.000.000
    Damit ist man schon weit über einen 64bit integer, man muss also BigInteger nehmen, aber dann hast du keine Hardware Unterstützung mehr.
    Ich habe das mal getestet, dabei waren floats am schnellsten, double am zweitschnellsten, dann int und long knapp dahinter. Mit ca. Faktor 10 langsamer als double weit abgeschlagen BigInteger.


    Und wenn man dann Berechnungen auf die GPU auslagert, dann ginge das mit BigInteger erst gar nicht, und GPUs sind wahre Fließkomma-Rechenmonster.

  • Jede Zahl egal ob Integer, double, long, Fließkommazahlen oder BigInteger muss vor jeder Berechnung erst in ein binäres Format umgerechnet werden. Also so was hier: 01010110101010110101010101010101...
    Stimmst du so weit zu?


    Und diese Umrechnung ist bei Fließkommazahlen besonders kompliziert.
    Siehe Wikipedia artickel zum Umrechnen https://de.wikipedia.org/wiki/Gleitkommazahl
    Ich behaupte nun das Fließkommazahlen eben nicht sehr schnell umgerechnet werden können.
    Im Gegenteil, das dauert länger als wenn man gleich ne Zahl ohne Komma hat. (Die dann natürlich dementsprechend lang sein muss um die gleiche Genauigkeit zu realisieren)


    Mag sein das ich da falsch liege. Das liegt natürlich auch an der verwendeten Programmiersprache. Ich kann nur Java und dort ist BigInteger mit beliebig langen Zahlen wesentlich effektiver.

    Durch das Lesen akzeptierst du meine EULA!

  • Jede Zahl egal ob Integer, double, long, Fließkommazahlen oder BigInteger muss vor jeder Berechnung erst in ein binäres Format umgerechnet werden. Also so was hier: 01010110101010110101010101010101...
    Stimmst du so weit zu?

    Warum sollte das vor jeder Berechnung geschehen? In der Regel Arbeitet man mit Variablen, die schon binär im Speicher liegen. Da braucht nicht viel Umgerechnet zu werden, außer z.B. bei Ein und Ausgaben (GUI usw.), das in Summe der ganzen Logik eines Programmes nicht ins Gewicht fällt. Und die CPU kann direkt mit den Binärdaten aus dem Speicher Rechnen.
    Bei einem BigInteger in C# werden die Bits intern als uint Array gespeichert. Da kann man den Prozessor nicht eben mal sagen, addiere Speicher X mit Speicher Y.


    Bei Java ist das nicht viel anders, ich habe das heute aus Interesse mal getestet, hatte im Grunde ein ähnliches Ergebnis, eigentlich schon sogar langsamer.
    In einer Schleife mit 1.000.000.000 Durchläufen einen Wert mit dem incrementierten schleifenzahl multipliziert
    c#
    double ca. 2,3 - 2,8 Sekunden,
    BigIneger ca. 26 - 29 Sekunden


    Java
    double ca. 2,4 - 2,9 Sekunden,
    BigIneger ca. 28 - 33 Sekunden


    Wenn man jetzt annimmt man hat in KSP 500 Orbitobjekte (Müll, Planeten usw.)
    Jeder Position besteht aus 3 Werten sind schon 1500 verschiedene Werte
    Nimmt man pro Physic-Frame 50 Rechenschritte pro Orbitobjeten an, sind das 75.000 Berechnungen
    bei 50 Physics-Frames in der Sekunde wären das 75.000 * 50 = 3.750.000 Berechnungen Pro Sekunde, bei meinem Test waren das 0,76 Sekunden, also bereits 76% der Verfügbaren Zeit verbraucht, kaum noch Luft nach oben, da ich auch einen Schnellen PC habe.
    Und 50 Rechenschritte pro Orbitobjekt ist vermutlich viel zu niedrig gehalten. Bei einer Orbitvorausberechnung könnte das auch locker 600-1000 Schritte sein.

  • Ich habe den jetzt nur auf meinem Firmen Rechner im Büro, hier ist aber der C# Code, die Java Variante ist im Grunde das selbe:


    Code
    1. var w = new Stopwatch();
    2. w.Start();
    3. var two = new BigInteger(2);
    4. for (int i = 0; i < 1000000; i++)
    5. {
    6. var bi = new BigInteger(i);
    7. var result = two * bi;
    8. }
    9. w.Stop();
    10. Console.WriteLine($"BigInteger: {w.ElapsedMilliseconds / 1000f}");