Performance bricht ein! evtl. eine Erklärung ;)
-
Versteh ich das richtig: Du blähst eine Funktion, die 214748364 Mal aufgerufen wird, um "ein paar tausend Zeilen" auf und wunderst dich jetzt, dass das Programm dadurch langsamer wird!?
-
BadMAx schrieb:
ich habe hier ein Stück Code das in so etwas wie einer "for" schleife "214748364" mal eine gewisse Arbeit erledigt.
(...)
wächst die Funktion zwecks Erweiterungen um ein paar Zeilen Code evtl. mehrere Tausend
(...)
in der Funktion wird ziemlich viel gesprungen ( goto ).
Das ist ein Troll, oder?
-
jetzt mal etwas ernster!
Das ganze ist ein kleiner Interpreter der folgendes interpretiert:
mov r1, 0 mov r2, 214748364 LABEL: inc r1 mov r4, r1 xchg r3, r4 jine r1, r2, LABEL // Jump if not Equal
sind nur die Instruktionen implementiert um "diese Aufgabe" zu erledigen läuft das ganze ( GCC-4 ) in +- 2.5 Sekunden durch ( CLANG ) sogar in -+ 1.5.
So jetzt zum Problem:
Werden weitere Instruktionen Implementiert bricht irgendwann die Performance ein und das ganze steigt ( GCC-4 ) von 2.5 auf 3.5.
Das ganze geht so weiter wie mehr Instruktionen hinzukommen. Grob sind das alle +- 1000 Instruktionen ( wieso das so viele sind sei mal egal )Wie schon erwähnt kommen sich die Instruktionen ( Implementierung ) nicht in die Quere außer das sie die Funktion aufblähen. Und
das Ganze ist aus Performance Gründen mit recht vielen "goto's" in nur "Eine" Funktion implementiert.Mir ist bewusst das es so einiges gibt was da mitwirken tut und das Problem darstellen könnte: CPU Caches, Segmentierung, Short und Far Jump, ...
- bei Short / Far Jumps / Segmentierung könnte ich mir die Verdoppelung vorstellen aber nicht das es immer weiter in den Keller geht
Hat irgend einer eine Vorstellung wo es hacken könnte oder ist die normal? Und kann man da irgendwie entgegenwirken?
Falls jemand was weiß "bitte" Ausführliche Erklärung falls möglich
( ein einfaches Geht/Geht nicht ist nicht Befriedigend
)
Die Funktion wird nur "ein" mal aufgerugen! Währen sie Läuft interpretiert sie erwähnten Code der Zuvor aus einer File gelesen wurde.
Gruß
-
BadMax schrieb:
Zum Vergleich. Folgendes in "C" ( GCC-4 -O0 ) läuft in 1.7 Sekunden durch:
Well, there's your problem...
Würde mich sehr stark wundern, wenn die GCC Variante etwas anderes als 0 Sekunden braucht, sobald du dem Compiler erlaubst, zu optimieren...
-
Das ist mir klar. Deswegen auch "-O0" damit er den Code nicht entfernt. Da der Interpreter die auch nicht tut ist so ein Vergleich möglich.
- Aber das war ja nur am Rande!Das Eigentliche Problem Steht Tiefer und hat so gesehen mit dem "C" Vergleichscode nichts zu tun
-
Sry, aber ich hab absolut keine Ahnung worauf du hinaus willst, dein Vergleich ist doch völlig sinnlos, wenn du den Compiler nicht optmieren lässt!? Klar wird der Compiler hier aufgeblähten Code erzeugen, durch -O0 sagst du ihm doch, dass er genau das tun soll!?
-
So habe die verwirrenden Stellen entfernt. Jetzt sollte es "doch" klarer sein. Vor allem wenn man den Ganzen Text liest
-
BadMax schrieb:
ich habe hier ein Stück Code das in so etwas wie einer "for" schleife "214748364" mal eine gewisse Arbeit erledigt.
Probiers doch mit loop unrolling, da geht deine Performance bestimmt wieder hoch
So groß ist der Performanceverlust doch gar nicht. Immerhin fügst du 1000 oder mehr Zeilen ein die dann 214748364 mal aufgerufen werden und hast dafür gerade mal eine eine Sekunde längere Laufzeit.
Seh ich es richtig das das ein ARM Prozessor ist? Wenn diese sowas wie "rdtsc" unterstützen dann kannst du ja mal mit der Zeit schauen ob das ganze vom Takt her so ungefähr hinkommt.
-
BadMax schrieb:
der ganze Spaß ist in eine Funktion Implementiert und läuft in +- 2.5 Sekunden durch.
wächst die Funktion zwecks Erweiterungen um ein paar Zeilen Code evtl. mehrere Tausend
bricht die Performance ordentlich ein +- 3.5 Sekunden
Also ohne mehr zu rechnen?
- Die erweiterungen kommen dem Code der die Arbeit erledigt nicht in die Quere sondern blähen höchstens die Funktion auf.
woran ( könnte ) liegt das genau? weiß einer was? und wie könnte man dem Entgegenwirken.
Vielleicht schlecht alignte Sprungziele. Das behebe ich mal, indem ich -march=native dazuschreibe und mal, indem ich es wegmache.
- Gibt es Limits für Funktionen? ( Max. Instruktionen per Funktion )
Wäre mir neu. Und selbst wenn, dann wird's deswegen nicht lahmer, sondern dann würde der Compiler abbrechen.
eines sei noch erwähnt: in der Funktion wird ziemlich viel gesprungen ( goto ).
- könnte das was mit ( short/far jump ) zu tun haben?Gute Idee. Aber ich denke, die Zeiten sind rum, daß das viel ausmachen würde.
System: Windows 7 64 | Cygwin + GCC-4
Und welche Compilereinstellungen?
-
Wenn die Funktion sooo groß ist, können da doch auch ein paar
cache misses
zuschlagen. Oder etwas in der Art.
-
Hi,
Also ohne mehr zu rechnen?
- jup
Vielleicht schlecht alignte Sprungziele. Das behebe ich mal, indem ich -march=native dazuschreibe und mal, indem ich es wegmache.
- hatte ich schon probiert. leider ohne Erfolg.
Und welche Compilereinstellungen?
- gcc-4 -O3 -std=c99
Wenn die Funktion sooo groß ist, können da doch auch ein paar cache misses zuschlagen. Oder etwas in der Art.
- sie ist/wird sehr groß
Gruß