Wiederverwendung von häufig aufgerufenem Code



  • 314159265358979 schrieb:

    Da ist nix falsch dran. Jeder einigermaßen moderne Prozessor heutzutage kann 64 Bit. Ein gewisser Fensterhersteller stellt dennoch 32-Bit OS her. Damit hinkt dieser ungefähr so weit hinterher, wie mit seinem C++-Compiler bei C++11. Na, wer errät, von welchem Unternehmen ich spreche? 🤡

    Die ganzen Pinguin-Hersteller machen das ebenso. Genauso wie die ganzen Teufelchen-Hersteller (Mal das Teufelchen für alle Unixe, sieht einfach toll aus) auch. Nur weil das ein gewisser fauler Apfel nicht mehr macht (?) hat das keine Aussage.

    Viele in meinem Bekanntenkreis haben noch 32bit Rechner, weil so ein Pentium mit 512 MB RAM und nem Linux/XP noch wunderbar für praktisch alles reicht.



  • Es kann durchaus Sinn machen 32 Bit noch zu unterstützen, aber es kann auch sehr viel Sinn machen solche Systeme zu vernachlässigen. Wenn man weiss, dass die Applikation hauptsächlich auf rechenstarken Maschinen, welche für Hochleistung gedacht sind optimal laufen soll, dann kann man es auch dafür auslegen. 32 Bit wird dann ja auch noch ohne Umwege unterstützt, aber halt nicht optimal für das System ausgelegt. Zusätzlich kann man Prozessor Erweiterungen benutzen, welche man bei 64Bit Systemen bestimmt hat um das ganze noch mehr zu optimieren.

    @Eisflamme
    Ohne die genauen Umstände zu wissen und die etwas genauere Struktur dieser Funktionen zu kennen ist eine allgemeine Aussage eher schwer. Ohnehin wirst du um Testläufe nicht herum kommen wenn du effektiv wissen willst was besser ist.



  • Eisflamme schrieb:

    Die Frage ist, ob ich das irgendwie lösen kann? Wie würdet ihr vorgehen?

    Mach Dir auf einem Zettel eine Rechnung: Deine CPU bekommt soundso viele Takte pro Sekunde, deine Funktion wird 100 Tausend mal pro Sekunde aufgerufen - dividiere die beiden Zahlen und Du bekommst sozusagen die Anzahl der CPU Takte, die Deine Funktion pro Sekunde zur Verfügung bekommt - "Best Case" sozusagen, natürlich Pi-mal-Daumen - das ist aber ein Wert, mit dem man abschätzen kann, wie schnell deine Funktion überhaupt sein sollte. Nun kannst Du messen, wie viele CPU Takte Deine Funktion rechnet und mit diesem Wert kannst Du abschätzen, wie viele Takte musst Du überhaupt rausholen, damit die 100 Tausend Aufrufe innerhalb einer Sekunde fertig sein sollten. Dann weisst Du auch ungefähr, ob es realistisch ist und ob es sich lohnt, die Funktion zu optimieren.



  • Ist der Algorithmus schon auf Cachefreundlichkeit optimiert?
    Und könnte man vielleicht mit Indizierung der Datensätze irgendwas rausholen?



  • Hi,

    danke für die Antworten erstmal. Die Kundengruppe darf auch recht alte Maschinen nutzen und tut es. 32 Bit schließe ich also in keinem Fall aus.

    Es handelt sich bei dem Programm um ein Analysetool für Pokerhände, ich hatte ja schon häufiger in der Vergangenheit damit rumgespielt. Alle möglichen Kombinationen von 7 Karten werden in 64-Bit-Integern bitweise kodiert. Oft werden aber mehrere solcher Kombinationen eingegeben und damit durchlaufen. Das Durchlaufen geschieht durch einfaches Iterieren, deswegen lässt sich wohl nichts Indizieren und auch für den Cache eher nichts optimieren.

    Also mir geht es nur darum Code nicht mehrfach zu schreiben, das ist alles. Wenn ich den Code anfasse und das bei 5 Stellen nachbessern muss, ist das einfach sehr unpraktisch.

    Makros gefallen mir bisher immer noch am besten, ich denke, die werde ich auch nehmen. 🙂



  • Eisflamme schrieb:

    Zurzeit gibt es keine Auslagerung und daher auch keinen Funktionsaufruf. Mit Auslagerung gäbe es einen und wenn der Compiler diesen nicht komplett wegoptimiert, würde man das vermutlich schon merken.

    Willst du statt Vermutungen nicht eher Messungen anstellen?

    Mit dem Makro-Ansatz wäre ich vorsichtig, da entstehen recht schnell Fehler, z.B. weil ein Ausdruck mehrfach ausgewertet wird. Davon abgesehen musst du bedenken, dass inline -Funktionen nicht automatisch schneller sind. Sie können die Ausführung sogar verlangsamen, wenn sie zu viel Code enthalten.



  • wenn es dir wirklich nur darum geht, nicht redundanten code zu schreiben, dann lager wie du es selbst gesagt und erkannt hast, soweit es geht in funktionen aus.
    vielleicht kannst du es so designen, dass du z.b. funktoren nutzen kannst, dann sparst nochmal einige funktionen...



  • Skym0sh0 schrieb:

    vielleicht kannst du es so designen, dass du z.b. funktoren nutzen kannst, dann sparst nochmal einige funktionen...

    Und was würde das bringen? Dann hat man zusätzlich zur Funktion auch noch Konstruktor und Destruktor, die aufgerufen werden...



  • wie machts denn die stl?
    auch ein paar zusätzliche con-/destruktoraufrufe aber sehr viel unabhängigkeit

    ich meine, das halt in etwa wie die STL
    sprich funktionszeiger gehen ja auch



  • Äh ja. Ob man Funktionen an andere Funktionen übergibt oder sie direkt aufruft, ist ein Unterschied. Im zweiten Fall sind weder Funktionszeiger noch Funktoren sinnvoll, da sie nur eine unnötige Indirektion mit sich bringen, die im besten Fall die gleiche Performance wie der direkte Aufruf hat.



  • Nexus schrieb:

    Willst du statt Vermutungen nicht eher Messungen anstellen?

    Die erste vernünftige Antwort.



  • wzeit schrieb:

    Nexus schrieb:

    Willst du statt Vermutungen nicht eher Messungen anstellen?

    Die erste vernünftige Antwort.

    Ich habe in meinen beiden Posts darauf hingewiesen, dass er es testen muss um zu wissen was schneller ist, aber es scheint den TO nicht zu interessieren und stützt sich lieber auf Vermutungen.



  • Wenn Du ähnliche Funktionen zusammen fasst, dann wird dein Code insgesamt kleiner und passt eher in den Cache. Daher ist ein zusätzlicher Funktionsaufruf eventuell sogar ein Performancegewinn. Ohne Messung erhälst Du darauf aber keine Antwort.



  • Ich habe in meinen beiden Posts darauf hingewiesen, dass er es testen muss um zu wissen was schneller ist, aber es scheint den TO nicht zu interessieren und stützt sich lieber auf Vermutungen.

    Tut mir Leid, falls ich irgendwie mein Desinteresse bekundet haben sollte. Ich kam noch nicht dazu das zu messen, werde dies aber tun, sobald ich dazu komme. Dennoch natürlich auch danke für die nach dem Vorschlag gekommenen Antworten. 🙂



  • Eisflamme schrieb:

    Ich habe in meinen beiden Posts darauf hingewiesen, dass er es testen muss um zu wissen was schneller ist, aber es scheint den TO nicht zu interessieren und stützt sich lieber auf Vermutungen.

    Tut mir Leid, falls ich irgendwie mein Desinteresse bekundet haben sollte. Ich kam noch nicht dazu das zu messen, werde dies aber tun, sobald ich dazu komme. Dennoch natürlich auch danke für die nach dem Vorschlag gekommenen Antworten. 🙂

    Wie hast Du denn festgestellt, welche Code-Teile optimiert werden müssen 😕



  • Wenn eine Funktion 1M Mal pro Sekunde aufgerufen wird, ist es nicht schwierig darauf zu schließen, dass die optimiert werden muss. 🙂


  • Mod

    Und woher weißt du das?

    Warum sperrst du dich so gegen das Messen? Das ist eine Sache von ein paar Minuten und hinterher hast du ganz genaue Informationen da drüber was wie warum dein Programm langsam macht.

    Wenn du nicht weißt, wie du vorgehen sollst, weil du es noch nie gemacht hast, dann frag doch einfach (bitte Betriebssystem angeben), anstatt rumzueiern.



  • Wieso werde ich denn jetzt wieder so angefahren?

    Ich habe doch gesagt, ich werde es messen, sobald ich dazu komme. abc.ws Frage hab ich so verstanden, um welche Codeteile es sich grob handelt. Der Code, der so häufig ausgeführt wird, ist nicht wirklich komplex. Gemessen hatte ich bereits, welche Teile davon wie langsam sind, nur eben nicht, wie es mit oder ohne Funktionsauslagerung aussieht.

    Also bitte nicht in den Mund legen, ich sperre oder sträube mich gegen das Messen, das habe ich nie gesagt und es stimmt auch nicht.



  • Eisflamme schrieb:

    Wieso werde ich denn jetzt wieder so angefahren?

    Ist doch kein Mädchenpensionat hier 😉

    Eine Million Funktionsaufrufe ist natürlich eine Menge - hängt aber auch davon ab, was die Funktion so alles macht.
    Als Beispiel: Eine "normale" CPU (in einem PC) wird Pi-mal-Daumen mit 2 GHz getaktet. Braucht ein Funktionsaufruf 100 CPU-Takte - ergibt 100 Millionen CPU-Takte für eine Million Funktionsaufrufe. Verglichen mit 2 Milliarden Takte - nicht viel.
    Weil so große Zahlen, kann man immer wieder darauf reinfallen. Man "optimiert" dann irgendwas, was nicht wirklich viel ausmacht. Man "optimiert" an falscher Stelle.
    Es gibt noch einen nützlichen Trick, die CPU Takte in unsere "normale" Dimension zu bringen: Man sagt, ein CPU-Takt wäre eine Sekunde, dann entsprechen 2 Milliarden CPU-Takte was weiss ich wie viele Jahre. Dann kann man es sich besser vorstellen. Wenn jemand also sagt "meine Funktion wird Tausende Male pro Sekunde aufgerufen, ich muss sie unbedingt optimieren" - dann würde man gleich sehen, dass 1000 Mal pro Sekunde nicht viel sind, so einige Male im Jahr oder so, also höchstwahrscheinlich kein Grund, die Funktion zu optimieren (es sei denn, man hat Zeit und Muße dafür und wird vielleicht auch noch dafür bezahlt :)).



  • Die Funktion ist aber nicht nur das, was am häufigsten aufgerufen wird, sondern steht so gut wie alleine da. Die Ergebnisse werden unmittelbar ans UI befördert und die Vorarbeitung ist vernachlässigbar. Also ein wenig an Messungen tat ich bereits. 🙂

    Ich hoffe, das nimmt eure Sorge, dass ich an der falschen Stelle optimieren könnte. Danke vielmals für die Empathie!


Anmelden zum Antworten