Performance der Basisoperationen. Wie teuer ist...
-
Das ist aber m.E. weder eine Aussage zu oder gegen Inline-Coding.
Kannst Du erläutern, was Du darunter verstehst und wo hier insbesondere Vorteile oder Nachteile liegen.ich moechte jetzt keine groessere abhandlung ueber optimierungen auf superskalaren architekturen schreiben, darum nur kurz:
da es im urspruenglichen thema darum ging, welche befehle besonders schnell ausfuehrbar seien, muss man sich zunaechst vor augen halten, dass das rechenwerk, abgesehen vom bekannten pipeline-aufbau, seit dem pentium-1 aus einer ansteigenden anzahl unabhaengiger teile besteht; naemlich (mehrere) addierer, shifter, binaerlogik, multiplizier, dividiererer plus das ganze nochmal fuer fliesskomma und mehrmals bei multicore.
um die bestmoegliche performance zu erzielen, muss man das gesamte rechenwerk ideal auslasten - dabei kann inlining hilfreich sein.
-
jox schrieb:
Was meinst Du mit "vierer- oder gar achter-schritten"??? Kannst Du das etwas präziser ausdrücken?
Ich denke er will damit sagen, dass es effizienter ist gleich 4 bytes auf einmal auf Gleichheit (oder 0) zu testen als immer nur ein Byte. Also anstatt einzelne chars zu vergleichen lieber gleich ein int oder ein long.
-
TactX schrieb:
jox schrieb:
Was meinst Du mit "vierer- oder gar achter-schritten"??? Kannst Du das etwas präziser ausdrücken?
Ich denke er will damit sagen, dass es effizienter ist gleich 4 bytes auf einmal auf Gleichheit (oder 0) zu testen als immer nur ein Byte. Also anstatt einzelne chars zu vergleichen lieber gleich ein int oder ein long.
... und wie willst Du das performant machen???? Wie willst Du - performant und in C - überprüfen, ob eines von 4 bzw. 8 Bytes eines Wortes 0x00 ist???
-
-
TactX schrieb:
http://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
Mag ggf. genau dann super funktionieren, wenn die Character-Strings genau auf Wort-Grenzen beginnen, auf Wort-Grenzen enden und dann noch ein Vielfaches von 4 bzw. 8 lang sind. Das dem i.d.R. nicht so ist, wissen wir beide. Anderenfalls muss man am Anfang und am Ende noch einen Haufen Sonderbehandlungen machen, was den Code natürlich auch nicht übersichtlich und ggf. nicht schneller macht.
Aber sei's drum .... falls es schneller gehen sollte, kann man den Code natürlich auch als Makro implementieren und vielleicht ist er dann sogar immer noch schneller als der Funktionsaufruf. Einen Versuch ist es ja Wert...
P.S. Danke für den Link, ich schau mal, was ich da so von gebrauchen kann
-
Mag genau dann super funktionieren, wenn die Character-Strings genau auf Wort-Grenzen beginnen
zb wenn man's mit "malloc" allokiert hat
Anderenfalls muss man noch einen Haufen Sonderbehandlungen machen
und genau das macht zb strlen.
deswegen ist deine trivial-implementierung auch auf kurzen strings pauschal schneller; bei langen strings (im sinne von kilobyte) relativiert sich dann der call-overhead schnell.
grundsaetzlich sollte man allignment aber bedenken - sonst waeren 128bit-prozessoren ja unnuetz...
-
hellihjb schrieb:
Mag genau dann super funktionieren, wenn die Character-Strings genau auf Wort-Grenzen beginnen
zb wenn man's mit "malloc" allokiert hat
Strings sind, so ist der heutige Stand, auf Byte-Grenzen ausgerichtet. Ich kann jederzeit einen char* pointer irgendwo mittenrein zeigen lassen (dann nützt mir auch der Basis-String mit malloc() nix) und das Ding hört leider auch nicht auf Wort-Grenzen auf...
hellihjb schrieb:
Anderenfalls muss man noch einen Haufen Sonderbehandlungen machen
und genau das macht zb strlen.
deswegen ist deine trivial-implementierung auch auf kurzen strings pauschal schneller; bei langen strings (im sinne von kilobyte) relativiert sich dann der call-overhead schnell.... mal ne blöde Frage, wieviel Strings haben eine solche Länge. Ich schätze mal, dein Vorname, Nachname, Wohnort usw. sind wohl entscheidend kürzer. Selbst bei Filenamen und URL's kommt man kaum auf kBs. Probier es einfach aus, manchmal überholt die Praxis die Theorie.
hellihjb schrieb:
... - sonst waeren 128bit-prozessoren ja unnuetz...
Das ist zwar ein ganz anderes Thema, aber: Hast Du schon mal 32-Bit-Prozessoren mit 64-Bit-Prozessoren verglichen? Ich schon (SUN/Solaris). Das Ergebnis würde Dich überraschen. Aber ich will hier keine pauschalen Äußerungen machen. Probier's oder google mal ein wenig zu diesem Thema.
-
jox schrieb:
Mag ggf. genau dann super funktionieren, wenn die Character-Strings genau auf Wort-Grenzen beginnen, auf Wort-Grenzen enden und dann noch ein Vielfaches von 4 bzw. 8 lang sind. Das dem i.d.R. nicht so ist, wissen wir beide. Anderenfalls muss man am Anfang und am Ende noch einen Haufen Sonderbehandlungen machen, was den Code natürlich auch nicht übersichtlich und ggf. nicht schneller macht.
Nun eben das hat volkard vorhin schon mehr oder weniger so gesagt.
-
TactX schrieb:
Nun eben das hat volkard vorhin schon mehr oder weniger so gesagt.
... ich weiß, aber warum wird man hier kritisiert, wenn man hier etwas wiederholt bzw. wenn man das Wort "überlegt" für andere Leute etwas präzisiert?
... oder war das keine Kritik?
-
jox schrieb:
Aber sei's drum .... falls es schneller gehen sollte, kann man den Code natürlich auch als Makro implementieren und vielleicht ist er dann sogar immer noch schneller als der Funktionsaufruf. Einen Versuch ist es ja Wert...
jetzt, wo ich deine messung widerlegt habe, kann ich ja mal versuchen, anzufangen, sich von deiner makromanie wegzubringen.
-
GPC schrieb:
manchmal sind echte inline-Funktionen schneller, manchmal Makros...
zeig mir ein beispiel. und nicht eins, wo die inlinefunktion so riesig ist, daß der compiler sie einfach nicht inlined.
-
mal ne blöde Frage, wieviel Strings haben eine solche Länge. Ich schätze mal, dein Vorname, Nachname, Wohnort usw. sind wohl entscheidend kürzer.
absolut richtig. aber ein string kann zb auch aus einer xml-datei kommen und eine ascii-repraesentation von mehreren tausend fliesskomma-zahlen beinhalten.
je nachdem, welche art von daten man nun hat, ist eben die eine oder die andere umgehensweise dafuer geeigneter - deshalb ist haeufig der einsatz irgendeiner maechtigen string-klasse nicht auch pauschal ideal.
und - uebrigens voellig kritikfrei - wenn man einen algorithmus in einem bestimmten testfeld fuer performanter befunden hat, sollte man auch erwaehnen, wie dieses testfeld aussieht.
-
hellihjb schrieb:
...je nachdem, welche art von daten man nun hat, ist eben die eine oder die andere umgehensweise dafuer geeigneter - deshalb ist haeufig der einsatz irgendeiner maechtigen string-klasse nicht auch pauschal ideal.
und - uebrigens voellig kritikfrei - wenn man einen algorithmus in einem bestimmten testfeld fuer performanter befunden hat, sollte man auch erwaehnen, wie dieses testfeld aussieht.Darauf können wir uns locker einigen
Mein Ansatz war aber nicht irgendwelche String-Operationen, sondern ging auf das ursprüngliche Thema ein, wieviel CPU-Zeit ein Befehl braucht. Mal so ganz grob zusammengefasst: Ich habe gesagt, bei den heutigen Prozessoren kann man das nicht mehr so einfach sagen, da muss man u.a. den Prozessor-Cache berücksichtigen. Dann habe ich mal so als unverbindliches Beispiel Inline-Code angeführt, dass man eben hierdurch ggf. erhebliche Performance-Gewinne erzielen kann. Selbstverständlich kommt es dabei auf die Anwendung an. Tut mir wirklich leid, dass das unverbindliche Beispiel nun ausgerechnet ein strlen()-Ersatz war. War halt nur ein Beispiel, was man mit Hilfe des Prozessor-Caches (und ggf. weiterer interner paralleler Abarbeitungen) erreichen kann. Man kann halt für einen Algorithmus nicht mehr einfach die Prozessorzyklen ermitteln und zusammenzählen (wie beim 80386), sondern muss halt noch mehr berücksichtigen. Mehr wollte ich nicht sagen
-
jox schrieb:
Dann habe ich mal so als unverbindliches Beispiel Inline-Code angeführt, dass man eben hierdurch ggf. erhebliche Performance-Gewinne erzielen kann.
inline im sinnne von inlinefunktiionen und makros wolltest du damit nicht trennen und die beiden sind für dich praktisch gleich und die verwendung des makros war nur sozusagen ein versehen?
-
volkard schrieb:
jetzt, wo ich deine messung widerlegt habe, kann ich ja mal versuchen, anzufangen, sich von deiner makromanie wegzubringen.
Tatsächlich? Wer hat was widerlegt? Ich habe auch keine Makromanie, sondern setze Macros nur ganz gezielt ein.
Mach ich hier bei irgendeinem Quiz mit? Gibt's eine Waschmaschine zu gewinnen?
-
jox schrieb:
komisch. vielleicht sollte man daran was ändern.
komisch. das ist anderenorts anders.
-
volkard schrieb:
...
inline im sinnne von inlinefunktiionen und makros wolltest du damit nicht trennen und die beiden sind für dich praktisch gleich und die verwendung des makros war nur sozusagen ein versehen?Ein einfaches Ja (bis auf das Versehen). Ich kann natürlich Inline-Code auch direkt in den Code reinhacken, aber wer macht das schon? Wie ist mir egal, Hauptsache der Code landet mit großer Wahrscheinlichkeit durch Prefetching im Prozessor-Cache. ... denn es ging mir um ein anderes Thema (zur Sicherheit wiederhole ich mich hier noch einmal):
Mein Ansatz war aber nicht irgendwelche String-Operationen, sondern ging auf das ursprüngliche Thema ein, wieviel CPU-Zeit ein Befehl braucht. Mal so ganz grob zusammengefasst: Ich habe gesagt, bei den heutigen Prozessoren kann man das nicht mehr so einfach sagen, da muss man u.a. den Prozessor-Cache berücksichtigen. Dann habe ich mal so als unverbindliches Beispiel Inline-Code angeführt, dass man eben hierdurch ggf. erhebliche Performance-Gewinne erzielen kann. Selbstverständlich kommt es dabei auf die Anwendung an. Tut mir wirklich leid, dass das unverbindliche Beispiel nun ausgerechnet ein strlen()-Ersatz war. War halt nur ein Beispiel, was man mit Hilfe des Prozessor-Caches (und ggf. weiterer interner paralleler Abarbeitungen) erreichen kann. Man kann halt für einen Algorithmus nicht mehr einfach die Prozessorzyklen ermitteln und zusammenzählen (wie beim 80386), sondern muss halt noch mehr berücksichtigen. Mehr wollte ich nicht sagen
P.S.: Das andere Thema (Inline-Coding, Makros, Funktionen etc) ist zwar auch höchst interessant, aber darüber sollte man evtl. anderer Stelle genüßlich philosophieren.
-
volkard schrieb:
GPC schrieb:
manchmal sind echte inline-Funktionen schneller, manchmal Makros...
zeig mir ein beispiel. und nicht eins, wo die inlinefunktion so riesig ist, daß der compiler sie einfach nicht inlined.
Ein Beispiel für was? Eins bei dem Macros schneller sind als Funktionen? Ich hab grad keins parat, aber da du ja auch im Besitz von Programming Pearls bist, verweise ich dich auf Column 9, Page 89, das max(a,b) Makro ganz unten. Hier halbiert das Makro die Laufzeit.
Im gleichen Absatz befindet sich auch ein Verweis auf 8.3, Page 79-80, hier erhöht sich die Laufzeit des floatsum3 - Algos (maximalen Subvektor eines Vektors herausfinden) um den Faktor 10 000, wenn man ein Makro anstatt eine Funktion benutzt.
Es ist jetzt schon gute 10 (oder auch 20, je nach Kapitel) Jahre her, dass diese Beispiele geschrieben wurden. Die Compiler sind in dieser Zeit sicherlich den ein oder anderen Tick besser geworden, allein das dürfte schon einiges an der Grundperformance des Programms gedreht haben.
Wie auch immer, ich überlasse dem Compiler die Arbeit. Soll er doch zuerst schauen, was er für am Besten hält. Reicht es mir von der Performance noch nicht, kann ich immer noch rumexperimentieren... kommt aber äußerst selten vor, dass ich in dieser Situation lande.Erst kürzlich hab ich ein kleines Programm für's Studium geschrieben, welches den Cache analysiert. In dem Zusammenhang könnte man ja mal schauen, ob ein Makro anstatt der Funktion was verändert. Ich vermute eher nicht. Aber wie gesagt, Messergebnisse sind in solchen Fällen sinnvoller als Vermutungen.
MfG
GPC
-
GPC schrieb:
Ein Beispiel für was? Eins bei dem Macros schneller sind als Funktionen?
nee, eins wo makros schneller sind als *inline*-funktionen.
-
@jox
Optimierung ist ja schön und gut, aber dein Makro bringt dir nur Nachteile. Glaub es mir, intrinsic Funktionen wie strlen wirst du nicht besser hinbekommen als ein Compiler. Früher mag das ja ein netter Zeitvertreib gewesen sein, und hat durchaus etwas gebracht, weil man zB Befehlserweiterungen wie MMX benutzen konnte, welche Compiler nicht beherrschten. Heutzutage bringt das bei solchen Sachen aber nichts mehr.
Ich habe das Makro einfach mal durch einen einfachen Benchmark geschickt (gcc -O3), mit 5, 20 und 100 Zeichen Strings. Und bereits bei 5 Zeichen war dein Makro ca. doppelt so langsam, bei 100 Zeichen ca. 3 mal so langsam. Es wird nach oben hin also nicht besser, was auch nicht zu erwarten war. Wenn du deine Tests natürlich nur mit -O laufen lässt, ist ja klar, dass durch kaum vorhandene Optimierung handgeschriebene Algos besser zur Geltung kommen. Für aussagekräftige Ergebnisse ist dies jedoch vollkommen nutzlos.
Mir scheint einfach, dir ist das Konzept von Release und Debug Builds unbekannt.jox schrieb:
Da irrst du dich.
jox schrieb:
, die Nachteile beim Debuggen überwiegen.
Ein entsprechender Debug Build hat keine Nachteile beim Debuggen.