Berechnung vereinfachen



  • Moin,

    ich habe folgende Formel die einen Rotationsfaktor anhand der Gewichtung von zuvorigem Faktor (ro), Rotationsziel (rt) und einem Zähler (rc) berechnet.

    float r = (ro + (rt - ro) * ((sin((-M_PI_2) + (M_PI * rc)) + 1.0) / 2.0));
    

    Instinktiv, wie ich an solche Sachen rangehe, habe ich die Formel durch Mathematica wie folgt vereinfachen lassen:

    float r = ro - 0.5 * (ro - 1.0 * rt) * (1.0 - (1.0 * cos(M_PI * rc)));
    

    Das funktionert prima (also korrekt), jedoch würde mich interessieren ob jemand auf anhieb erkennen kann, ob diese Vereinfachung etwas bringt. Mir fehlt die Erfahrung. 😉
    Auch fehlt mir die Erfahrung den Unterscheid in einer empirischen Schleifenstudie zu messen. Ich bin heilfroh, das die Funktion tut was sie tut. 😉



  • vorher:
    4 mal +-
    2 mal *
    1 mal /

    Danach
    3 mal +-
    5 mal *
    0 mal /

    Also das das / weg ist ist eigentlich gut, ist aber bei x/2 nicht so schlimm, weil der Compiler es zu einem shift optimieren müsste.
    Sonnst haste es eher verschlimmert. Nimm die 1. Version und ersetze das /2.0
    vorsichtshalber mal duch nen *0.5

    (Obwohl: Sind Multiplikationen wirklich langsammer als Additionen bei Fließkommazahlen? wegen Basis anpassen und so)



  • MisterX schrieb:

    Also das das / weg ist ist eigentlich gut, ist aber bei x/2 nicht so schlimm, weil der Compiler es zu einem shift optimieren müsste.

    Bei Fließkomma? Da kann er höchtens mit Bitgeschubse den Exponenten dekrementieren (inklusive Checks usw.). Ich bezweifle aber, dass Compiler das machen.



  • Folgendes ist schon mal hochoptimierter™ als zuvor:

    float r = ro + ((-ro + rt) * (0.5 - (0.5 * cos(M_PI * rc)
    

    Sind schon mal beachtliche 7 zu 6 Operanden und ohne Division. Mathematica ist mein Freund. 😉
    Muss man das Minus vor <ro> einklich™ mitrechnen? (-variable) ist doch auch ein Ausdruck der durch den Prozessor erstmal augewertet werden muss, oder?

    Sonst erstmal danke allerseits.



  • was sagste zu dem:

    r = (ro - rt)*cos(M_PI*rc)/2 + (ro + rt)/2
    


  • Was mich wiederum zu folgendem führt:

    r = 0.5 * (ro + rt + (ro - rt) * cos(M_PI * rc));
    

    Jetzt habe ich (wenn ich mich recht entsinne) 5 funktionierende Schnippsel. Mh, ich sehe schon, ich komme um eine Feldstudie nicht herum. 🙂



  • Ehrliche Meinung: Lass es. Lass den Compiler Compiler sein, der weiss wahrscheinlich eh besser was gut für ihn ist.



  • TactX schrieb:

    Lass es. Lass den Compiler Compiler sein, der weiss wahrscheinlich eh besser was gut für ihn ist.

    manchmal muss man aber etwas nachhelfen....



  • net schrieb:

    TactX schrieb:

    Lass es. Lass den Compiler Compiler sein, der weiss wahrscheinlich eh besser was gut für ihn ist.

    manchmal muss man aber etwas nachhelfen....

    Sicher. Aber daran würde ich mich erst setzen wenn ich weiss, dass die Berechnung wirklich wichtig ist ("Bottleneck") und dass der Compiler vielleicht nicht so toll optimiert wie erhofft. Blind drauflos optimieren ist imho Zeitverschwendung.



  • TactX schrieb:

    Aber daran würde ich mich erst setzen wenn ich weiss, dass die Berechnung wirklich wichtig ist ("Bottleneck")...

    du siehst das viel zu nüchtern. manchmal macht sowas einfach nur spass...

    TactX schrieb:

    Blind drauflos optimieren ist imho Zeitverschwendung.

    'blind' sowieso nicht. damit erreicht man meistens das gegenteil.



  • Ja! Und ich wollte gar nicht mal bis zum Nimmerleinstag optimieren. Nein, ich wollte was lernen bzw. verstehen. Als Neuling in Sachen C ist man sich gelegentlich unsicher, und wie an verschiedenen Stellen hier im Forum schon bewiesen wurde, kann man durch ebensolche Fragen Licht ins Dunkle bringen. Und das macht Spaß!

    Vielen Dank und es werde Licht! 🙂


Anmelden zum Antworten