std::inf nicht für -Ofast bzw. -ffast-math gedacht!?



  • #include <limits>
    #include <iostream>
    #include <cmath>
    
    int main(){
        double num =  std::numeric_limits<double>::infinity();
        std::cout << std::isinf(num) << std::endl;
        std::cout << (num==INFINITY) << std::endl;
    }
    

    Wenn man beim kompilieren -ffast-math bzw. -Ofast angibt kommt 0 und 1 raus, ohne 1 und 1.

    sollte man da vorsichtshalber immmer:

    std::cout << (num==INFINITY || num==-INFINITY) << std::endl;
    

    statt isinf schreiben?


  • Mod

    Deshalb stehen bei Ofast & Co. auch dicke Warnungen dran, dass da nicht unbedingt die erwarteten Ergebnisse raus kommen und man deswegen verdammt vorsichtig sein sollte. Die Annahme, dass niemals inf oder nan vorkommt ist typisch für diese Art von Optimierung.



  • SeppJ schrieb:

    Deshalb stehen bei Ofast & Co. auch dicke Warnungen dran, dass da nicht unbedingt die erwarteten Ergebnisse raus kommen und man deswegen verdammt vorsichtig sein sollte. Die Annahme, dass niemals inf oder nan vorkommt ist typisch für diese Art von Optimierung.

    Aber der Vergleich mit INFINITY funktioniert ja noch. D.h std::isinf wird immer auf false gesetzt?


  • Mod

    asdfqwertz schrieb:

    Aber der Vergleich mit INFINITY funktioniert ja noch. D.h std::isinf wird immer auf false gesetzt?

    Ich würde an deiner Stelle einfach von undefiniertem Verhalten ausgehen, sobald mit Ofast inf- oder nan-Werte auftreten. Und auch sämtliche anderen Klugscheißersonderfälle von Fließkommazahlen (Subnormalen, Signed Zero, ...) würde ich möglichst vermeiden. Es ist halt nicht genau festgelegt, was genau funktionieren wird und unter welchen Umständen. Der Sinn der Sache ist nicht, maximal auszureizen, was mit dieser Optimierung noch geht, sondern stattdessen, dass du guckst, ob deine Rechnung trotz dieser Optimierung noch geht. Falls deine Rechnung das Funktionieren der erwähnten Klugscheißersonderfälle zwingend voraussetzt, kannst du es eigentlich gleich vergessen.



  • asdfqwertz schrieb:

    Aber der Vergleich mit INFINITY funktioniert ja noch. D.h std::isinf wird immer auf false gesetzt?

    Siehe z.B. https://gcc.gnu.org/wiki/FloatingPointMath

    Das steht, dass -ffinite-math-only implizit mit dem -ffast-math angenommen wird. Und das erlaubt dem Compiler eben diverse Dinge anzunehmen. Dort steht nicht, dass es immer auf false gesetzt wird.



  • SeppJ schrieb:

    asdfqwertz schrieb:

    Aber der Vergleich mit INFINITY funktioniert ja noch. D.h std::isinf wird immer auf false gesetzt?

    Ich würde an deiner Stelle einfach von undefiniertem Verhalten ausgehen, sobald mit Ofast inf- oder nan-Werte auftreten. Und auch sämtliche anderen Klugscheißersonderfälle von Fließkommazahlen (Subnormalen, Signed Zero, ...) würde ich möglichst vermeiden. Es ist halt nicht genau festgelegt, was genau funktionieren wird und unter welchen Umständen. Der Sinn der Sache ist nicht, maximal auszureizen, was mit dieser Optimierung noch geht, sondern stattdessen, dass du guckst, ob deine Rechnung trotz dieser Optimierung noch geht. Falls deine Rechnung das Funktionieren der erwähnten Klugscheißersonderfälle zwingend voraussetzt, kannst du es eigentlich gleich vergessen.

    Wenn ich ==INFINITY verwende funktioniert mein Programm auch mit -Ofast. Mit isinf und -Ofast kommt totaler Mist bei raus 🙂


  • Mod

    asdfqwertz schrieb:

    Wenn ich ==INFINITY verwende funktioniert mein Programm auch mit -Ofast. Mit isinf und -Ofast kommt totaler Mist bei raus 🙂

    Willst du das jetzt für jede Kombination von GCC-Version, glibc-Version, Optimierungsstufe (neben Ofast), umgebenden Code, Rechenwerk, und Befehlssatz ausprobieren? Oder glaubst du uns, die du danach gefragt hast, dass das Verhalten von Unendlichkeiten mit Ofast nicht verlässlich ist? Es steht schließlich explizit in der Anleitung (siehe wob), dass Ofast die Annahme anschaltet, dass alle Werte endlich sind. Wenn du diese Annahme verletzt, ist das Verhalten undefiniert. Wenn du undefiniertes Verhalten nicht akzeptieren kannst (Du solltest es keinesfalls akzeptieren!), und in deinem Programm Unendlichkeiten auftreten, dann kannst du kein Ofast benutzen. Punkt.


Anmelden zum Antworten