Unterschied von Gleitkommaberechnungen zwischen Release und Debug



  • Ich habe ein kleines Problem. Und zwar ich will einen 2D-Punkt auf ein 3D-Dreieck abbilden. Der Punkt soll also eine Höhe bekommen so dass dieser genau in der Ebene des Dreiecks liegt.

    Das Ganze ist schon unter VC2003 (C++) implementiert und getestet. Doch stellte ich fest, dass sich die Ergebnisse der Debug Version minimal von der der Release Version unterscheiden. Der Unterschied ist zwar nur 1E-16, doch genügt das Ganze um den Rest des Programms ins Chaos zu stürzen.

    Ein Softwarefehler scheint bald ausgeschlossen (außer ich zerschiesse mir irgentwo meinen Speicher oder die Einstellungen für <math.h>). Man kann den Fehler eins zu eins bis an eine Berechnung der folgenden Form zurückverfolgen. Alle Eingangsdaten (triangle, lamda, gamma) sind in der Debug und Release gleich. Die Ausgangsdaten (proj_point) sind aber in beiden Versionen unterschiedlich.

    proj_point->x = triangle.a->x + lamda * (triangle.b->x - triangle.a->x) + gamma * (triangle.c->x - triangle.a->x);
    proj_point->y = triangle.a->y + lamda * (triangle.b->y - triangle.a->y) + gamma * (triangle.c->y - triangle.a->y);
    proj_point->z = triangle.a->z + lamda * (triangle.b->z - triangle.a->z) + gamma * (triangle.c->z - triangle.a->z);
    

    Ein Wechsel auf VC6 brachte auch keinen Unterschied.

    Deswegen meine Frage: Kannn es möglich sein dass Berechnungen mit Gleitkommazahlen in der Debug zu minimal anderen Ergebnissen führt als in der Release ?

    Danek



  • Ich vermute ein Unterschied der Auswertungsreihenfolge.

    D.H. der Compiler optimiert im Release den Code so, dass möglichst wenig Zwischenergebnisse anfallen. Im Debug 'notiert' er Zwischenergebnisse mit endlicher Genauigkeit, wobei dann Ungenauigkeiten in das Endergebnis einfließen.



  • Du solltest auf jeden Fall prüfen, ob die Gleitkomma Optionen des Compilers für Release und Debug identisch sind (/fp).
    Eine zweite Möglichkeit ist, dass im Debug Build Runtime Funktionen verwendet werden, im Release Build jedoch Intrinsics, die direkt auf CPU Instruktionen abgebildet werden können.
    Allerdings würde ich mir weniger Sorgen um die Unterschiede zwischen Release und Debug machen, als vielmehr um deinen Code selbst. Wenn abweichende Genauigkeiten deine Anwendung in die Wüste schicken, ist eher die Logik des Codes das Problem.



  • Ja da hast dur Recht. Das Problem liegt in der Logik des Codes oder genauer gesagt in die Logik der Aufgabe, denn ich habe da so einige numerisch instabile Algorithmen aus der Computergrafik und die sind von Natur aus anfällig. Beispiele dafür sind der PunktAufLinie-Test (Kolinearitäts-Test), Inkreis-Test, konvexe Hülle, PunktLinksVonLinie-Test, PunktInDreieck-Test, PunktInPolygon-Test, ...

    Ich habe mal die Compileroptionen soweit geprüft und sie dürften in Ordnung sein. Damit schliest sich der Kreis der Verdächtigen auf Zwei ein. Entwedet macht der Compiler wie du schon gesagt hast Unterschiede zwischen Debug und Release und "optimiert" da wild durch die Gegend rum (obwohl ich das ihm verboten habe) oder es liegt daran das einige Libs mal wieder an dem Gleitkommapacket rumfummeln obwohl sie das eigentlich nicht sollten. Ich hatte das Problem schon einmal mit den Libs von DirectX 9.0. Die DirectX Libs haben bei mir die Berechnungsgenauigkeit heruntergeschraubt, so dass alle Folgeberechnungen massiv schlechter wurden.


Anmelden zum Antworten