Ich hasse Numerik



  • Ich muss das einfach nur mal loswerden:

    Tests Debug 64 Bit: 33/33 pass
    Tests Release 64 Bit 33/33 pass
    Tests Debug 32 Bit 11/33 pass
    Tests Release 32 Bit 31/33 pass

    Wtf? Ich hasse Numerik. 😡 Ich hasse sie, hasse sie, hasse sie! 😡 😡 Was ist an einem double in 32 Bit so anders als bei einem in 64? wie geht das? was geht da? 😡 😡 😡

    Danke, jetzt gehts mir besser



  • Troll!



  • otze schrieb:

    Was ist an einem double in 32 Bit so anders als bei einem in 64? wie geht das? was geht da?

    Ich könnte es dir erklären, wenn du wieder klarer im Kopf bist 😉



  • hihi



  • Bashar schrieb:

    Ich könnte es dir erklären, wenn du wieder klarer im Kopf bist 😉

    Alles klar, erklärs mir. Vielleicht noch als Randmerkung: ein test zählt als gescheitert, wenn die Genauigkeit unter 10^-15 sinkt. Beobachtete Phänomene: Algorithmen für den Gradientenabstieg (CG,BFGS...) divergieren, obwohl sie in 64 Bit stabil konvergent sind und fast alles funktioniert im 32-Bit Release Mode prächtig (bis auf ein Verfahren das wirklich fehlerhaft ist...).



  • Das hängt natürlich vom Compiler ab, aber falls es Visual C++ oder einer, der sich auch so verhält, ist: Im 32-Bit-Modus benutzt er die x87-FPU. Die besteht aus einem Stack von 80-Bit-Registern, alle Berechnungen werden also in 80 Bit ausgeführt. Zwischenergebnisse können im Speicher als 64-Bit-doubles abgelegt werden, müssen aber nicht. Es ist daher beispielsweise möglich, dass ein Wert ungleich zu sich selbst ist, wenn z.B. der eine Vergleichsoperand die ganze Zeit in der FPU war und der andere gerade frisch reingeladen wurde.
    Der 64-Bit-VC++ benutzt dagegen (standardmäßig) die SSE2-Einheit, die in 128-Bit-Registern mit 2 echten 64-Bit-Doubles gleichzeitig arbeiten kann. Du hast also nicht diese Effekte aufgrund abweichender interner Präzision.
    Ob das nun deine Fails erklärt, weiß ich nicht, aber es ist eine Antwort auf die Frage, die ich zitiert hatte.



  • AMD oder Intel? gcc, icc oder vc?



  • Klingt plausibel, was Bashar geschrieben hat. Demnach würdest Du eine für 64-Bit-Arithmetik zu hohe Genauigkeit erwarten und hast in drei von vier Fällen einfach das Glück, dass einige Rechnungen mit 80bit (oder mehr?) durchgeführt werden.

    Weil ich selbst mit nichtlinearen Ausgleichsproblemen zu tun habe, frag ich mal: Wie berechnest Du die partiellen Ableitungen und wie entscheidest Du, wann so ein iteratives Verfahren abgebrochen werden kann?



  • @knivil ich sitze leider gerade nicht im Institut und kann daher nix genaueres sagen. es ist auf jeden Fall ein gcc...

    @Bashar ja, das war mir auch bekannt...aber erklärt das auch den Unterschied zwischen Debug und Release? normalerweise würde ich ja erwarten, dass es im Debug funktioniert und im Release (-O3) Probleme gibt. Es ist aber genau umgekehrt?!?

    @krümelkacker Das sind ganz einfache Testfälle. Die Tests die zum Beispiel schief ghen sind einfache quadratische Funktionen für die ich die analytische Ableitung berechne (mit double Genauigkeit). Also eigentlich etwas, wo ein CG/BFGS gar nicht divergieren kann. In der Praxis ist es aber so, dass mein BFGS-Linesearch bei 32 Bit in der 2. Iteration gegen Unendlich läuft und der Suchpunkt dann irgendwann NaN ist. Es ist also kein einfaches "he, 10^-15 war ne zu harte Grenze", damit könnte ich leben oder würde etwas an der Anzahl der Iterationen für den Test rumschrauben. Aber da sist mal ne Nummer härter...

    Da unsere Mathematik komplett auf boost::ublas aufgebaut ist, haben wir momentan das im Verdacht. Ist aber nicht mehr als ein diffuses Gefühl.

    //edit achja beim CG testen wir bei der einzigen Division ob das Argument nicht 0 ist...und mehr kann da eigentlich kein NaN auslösen

    Danke an alle die sich meinen kurzen Rant angetan haben 😃



  • otze schrieb:

    @Bashar ja, das war mir auch bekannt...aber erklärt das auch den Unterschied zwischen Debug und Release? normalerweise würde ich ja erwarten, dass es im Debug funktioniert und im Release (-O3) Probleme gibt. Es ist aber genau umgekehrt?!?

    Welche Flags hast du denn gesetzt? Vielleicht hast du ja bei der Release-Version ein Flag gesetzt um SSE-Code generieren zu lassen (zB -march=native oder -mfpmath=sse).



  • otze schrieb:

    //edit achja beim CG testen wir bei der einzigen Division ob das Argument nicht 0 ist...und mehr kann da eigentlich kein NaN auslösen

    Man kann aber sehr leicht ein INF bekommen, was in weiterer Folge dann zu einen NAN führen kann (+INF + -INF gibt doch NAN, oder nicht?).



  • Ohh es schien wirklich Boost zu sein.

    Rebuild mit Version 1.45 und alle Fehler(bis auf die 2 die jetzt auch in 64 Bit reproduzierbar waren...) verschwanden im Debug Modus.

    Danke für euer Verständnis 🙂

    Numerik hasse ich aber immer noch.


Anmelden zum Antworten