Frage

Ich habe ein Software-Projekt, in der manchmal seltsame Ergebnisse von kleinen, einfach Gleitkommaoperationen ich. Ich nehme an, es ist etwas, was ich verpasst haben, und würde einige Tipps, wie, wie die folgenden Probleme zu debuggen:

(der Compiler verwendet wird, ist MS VC 6.0, dh Version 12 der Microsoft C-Compiler)

Erste Anomalie:

extern double Time, TimeStamp, TimeStep;  // History terms, updated elsewhere
void timer_evaluation_function( ) {
    if ( ( Time - TimeStamp ) >= TimeStep ) {  
        TimeStamp += TimeStep;  
        timer_controlled_code( );  
    }
{....}

Aus irgendeinem Grund die Zeitauswertung ausgefallen und der zeitlich abgestimmten Code nie ausgeführt. Im Debugger war es kein Problem, dass die trig Bedingung in der Tat wahr, um zu sehen, aber die FPU weigerte mich, ein positives Ergebnis zu finden. Das folgende Codesegment hatte keine Probleme, obwohl es die gleichen Operationen durchgeführt. Das Problem wurde umgangen, indem eine falsche Bewertung Einsetzen das es erlaubt werden könnte scheitern.

Ich bin der FPU Zustand zu raten ist irgendwie von früheren Operationen behaftet durchgeführt wird, und dass es einige Compiler-Flags, die helfen würde?

Zweite Anomalie:

double K, Kp = 1.0, Ti = 0.02;
void timed_code( ){
    K = ( Kp * ( float ) 2000 ) / ( ( float ) 2000 - 2.0F * Ti * 1e6 )
{....}

Das Ergebnis ist #IND, auch wenn der Debugger die Gleichung auf ca. 0,05 auswertet. Der #IND Wert erscheint in dem FPU-Stapel, wenn der Wert in die 2.0F FPU aus der Verwendung des FLD-Befehls geladen wird. Die vorherige Anweisung lädt den Integer-Wert 2000 als Doppel-Schwimmer der fild Anweisung verwendet. Sobald der FPU-Stack des #IND Wert enthält alles verloren, aber noch einmal der Debugger hat kein Problem mit der Formel auswertet. Später, geben diese Operationen die erwarteten Ergebnisse.

Auch, wenn wieder die FPU Probleme treten direkt nach dem Funktionsaufruf. Sollte ich Punktoperationen Einsatz, der den schwimmenden Zustand der FPU nach jeder neuen Funktion löscht? Gibt es einen Compiler-Flag, das die FPU in irgendeiner Weise beeinflussen könnten?

Ich bin dankbar, von irgendwelchen und alle Tipps und Tricks an dieser Stelle.

EDIT: Ich habe es geschafft, das Problem zu vermeiden, indem die Montagefunktion EMMS als erstes in der Top-Funktion aufrufen. Auf diese Weise der FPU besteht aus einem beliebigen MMX im Zusammenhang Müll gelöscht, die in der Umwelt nicht erstellt wurden, mein Code aus aufgerufen wird oder nicht. Es scheint, dass der Zustand der FPU ist nicht etwas für selbstverständlich zu nehmen.

// Frank

War es hilfreich?

Lösung

Wenn Sie die Fenster und Queryperformancecounter Queryperformance Funktionen auf einem System verwenden, das den FEMMS Befehls Einfügen nach der Frequenz / Zähler-Abfragen und vor der Berechnung MMX versuchen unterstützt.

__asm femms

Ich habe Probleme aus dieser Funktion angetroffen vor, wo sie 64-Bit-Rechen MMX taten und nicht mit dem Floating-Point-Flags / Zustand gelöscht wird.

Diese Situation könnte auch passieren, wenn es eine 64-Bit-Arithmetik zwischen den Floating-Point-Operationen ist.

Andere Tipps

Keine Ahnung, was das Problem sein könnte, aber auf x86, löschen die FINIT Anweisungen, um die FPU. Um Ihre Theorie zu testen, können Sie diese irgendwo im Code einfügen:

__asm {
    finit
}

Es ist nicht wirklich eine Antwort auf Ihre Frage, aber Sie könnten an zwei von Raymond Chen Artikeln über seltsames FPU Verhalten zu suchen. Nachdem Sie Ihre Frage zu lesen und wieder lesen Sie die Artikel, ich nicht sofort einen Link sehen - aber wenn der Code, den Sie eingefügt haben, ist nicht vollständig oder wenn die Artikel gibt Ihnen eine Vorstellung über einige umliegende Verhalten, die das Problem verursacht .. . insbesondere, wenn Sie eine DLL irgendwo in der Nähe sind geladen werden.

Uninitialized Gleitkommavariablen kann tödlich sein

Wie hat die ungültige Gleitkommaoperanden Ausnahme ausgelöst werden, wenn ich kann es deaktiviert?

Während ich nicht, dass Sie mit einer genauen Lösung bereitstellt, empfehle ich Ihnen beim Lesen dieser Artikel , die die verschiedenen Optimierungen beschreibt, die man verwenden kann.

re: Zeitstempel -

Was bekommen Sie Ihre Quelle des Zeitstempels aus? Etwas klingt verdächtig. Versuchen Sie, sie in einer Datei zu protokollieren.

Wenn der schlechte Wert von einem FLD geladen wird, die 2.0 geladen werden sollte, würde ich den Speicher prüfen, wo dieser Wert aus geladen wird -. Es könnte nur ein Compiler / Linker Problem sein

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top