PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] INLINE nicht eindeutig



Siro
15.01.2016, 10:13
Hallo zusammen, zum Wochenende eine kleine Frage:

Ich wollte meiner Software etwas unter die Arme greifen und unnötige Funktionsaufrufe vermeiden.
Also ein Speedup sozusagen.

Nun dachte ich (sollte man nicht, weis ich;)) durch das Schlüsselwort "inline" wird der Funktionscode
jeweils direkt eingesetzt ohne Funktionsaufruf. Das macht den Code zwar größer aber call und return entfallen.

Nun lese ich grad Folgendes und muss feststellen das ich durch inline NICHT unbedingt zum gewünschten Ziel komme :(

Quelle: https://de.wikibooks.org/wiki/C-Programmierung:_Funktionen#Inline-Funktionen

a) Eine Funktion, die als inline definiert ist, soll gemäß dem C-Standard so schnell wie möglich aufgerufen werden.
b) Die genaue Umsetzung ist der Implementierung überlassen.
c) Beispielsweise kann der Funktionsaufruf dadurch beschleunigt werden, dass die Funktion nicht mehr als eigenständiger Code vorliegt,
sondern an der Stelle des Funktionsaufrufs eingefügt wird.
Dadurch entfällt eine Sprunganweisung in die Funktion und wieder zurück.
d) Allerdings muss der Compiler das Schlüsselwort inline nicht beachten,
wenn der Compiler keinen Optimierungsbedarf feststellt.
f) Viele Compiler ignorieren deshalb dieses Schlüsselwort vollständig und setzen auf Heuristiken, wann eine Funktion inline sein sollte.


zu a) eigentlich soll die Funktion garnicht aufgerufen werden, sondern der Code direkt eingefügt werden.
zu b) verstehe ich nicht, die Implementierung ist doch mein code ?
zu c) genau das möchte ich
zu d) UPPS, das soll er aber unbedingt beachten, unabhängig von der Optimierungsstufe
zu f) damit ist inline für mich unsinnig geworden


Gibt es einen Zwangs-Paramter(Schlüsselwort), dass der Code "unbedingt" ohne Aufruf in den Code eingetragen wird ?

Ich danke Euch schonmal für Informationen

Siro

- - - Aktualisiert - - -

Habe noch etwas weiter gesucht und folgendes gefunden:

Inline Methoden

In der klassenorientierten Programmierung kommt es häufig vor, dass eine Methode nur aus einer einzigen Anweisung besteht. Dies geschieht besonders oft bei sogenannten Gettern. Hierbei ist der Aufwand, die Funktion zu rufen aufwendiger als das, was die Funktion eigentlich leistet.
In dem Fall kann man dem Compiler empfehlen, den Funktionsaufruf wegzulassen und die wenigen Anweisungen direkt da auszuführen, wo eigentlich die Funktion gerufen werden soll.
Eine inline-Funktion wird also überall da eingesetzt, wo eigentlich die Funktion gerufen werden sollte.

Also ist inline nur eine Compiler Empfehlung. Man kann es nicht direkt steuern :(

shedepe
15.01.2016, 10:23
Hey,
zu a) Von Wikipedia:
Es ist für den Compiler aber nicht für jede beliebig komplizierte Funktion möglich, die vom Programmierer gewünschte Ersetzung auch durchzuführen. Dann wird der normale Funktionsaufruf beibehalten.
Aus dem englischen Artikel: [quote]Complete inline expansion is not always possible, due to recursion (https://en.wikipedia.org/wiki/Recursion_%28computer_science%29): recursively inline expanding the calls will not terminate. [/qoute]
zu b) Nein die Implementierung des Standards macht der Compilerhersteller.
zu c) Von Wikipedia: [quote]Vielmehr ist das inline im Beispiel als Empfehlung an den Compiler zu sehen, der er aber nicht nachgehen muss[/qoute]
zu d) 1. Nein wenn die auf Size Optimierst dann wäre es für den Compiler ja falsch das zu machen. 2. Es gibt compiler spezifische Erweiterungen wie __forceinline die inline erzwingen
zu f) Der Compiler weis in der Regel besser zu Optimieren als du.

Lies dir mal den englischen Artikel dazu durch: https://en.wikipedia.org/wiki/Inline_expansion da wird das sehr genau beschrieben.

Siro
15.01.2016, 11:03
Ich danke Dir shedepe

Ich hab es mir grad durchgelesen und habe die Komplexität von inline völlig unterschätzt.
Je nach Code kann das echt problematisch werden für den Compiler. Wenn dann noch Paramter oder schlimmer Rekursionen auftreten, sollte man das lieber dem Compiler überlassen wie und ob er dort optimiert,
gebe ich Dir bzw. dem Compiler völlig recht.

Ich hatte nur eine Minifunktion die zwei Werte subtrahiert und wollte den Compiler dazu zwingen den Code als inline zu codieren.
Das tut er vermutlich sogar selbst wenn ich die entsprechenden Optimierungen setze.

Dann sind wird von meiner Seite schon durch mit dem Thema INLINE
und wünsche ein "optimales" Wochenende.
Siro

damfino
15.01.2016, 11:13
Mit
static inline void Fahrmotorencheck(void)__attribute__((always_inline )); schaffe ich es das diese Funktion immer inline ist.

Mache das aber nur für kleine in sich geschlossene Funktionen die oft aufgerufen werden.

Habe mal gelesen das es bei den Atmegas nicht so darauf ankommt da Funktionsaufrufe schnell abgearbeitet werden.

shedepe
15.01.2016, 11:15
Kleiner Tipp zum Thema Optimierung (von Hand):
Optimierung sollte man erst dann verwenden wenn man sie braucht. Wenn dein Programm das tut was es soll, und das schnell genug dann ist das gut so. In dem fall sollte man lieber auf sauberen, wartbaren Code achten.
Wenn man aber tatsächlich ein Performance Problem hat, dann sollte man seinen Code profilen. Z.B. mit Callgrind auf Linux. Ein Profiler zeigt dir an wie häuft ein bestimmter Funktionsaufruf gemacht wird.
Dann kann dort gezielt optimieren. Es bringt z.B. nichts eine Routine die nur einmal oder zwei mal aufgerufen wird zu optimieren. Wenn man hingegen eine Routine die alle 5ms aufgerufen wird, kann man viel mehr rausholen.

Peter(TOO)
15.01.2016, 13:01
Hallo Siro,

Ich hatte nur eine Minifunktion die zwei Werte subtrahiert und wollte den Compiler dazu zwingen den Code als inline zu codieren.
So etwas kann man als Macro realisieren:

#define add(a,b) (a)+(b);

MfG Peter(TOO)

shedepe
15.01.2016, 13:42
Bevor man Macro anstelle von inline Funktionen vorschlägt sollte man sich Gedanken drüber machen ob Macros wirklich Sinn machen.
Das ist die erste Zusammenfassung die ich auf die Schnelle gefunden habe:

https://stackoverflow.com/questions/1137575/inline-functions-vs-preprocessor-macros

Peter(TOO)
15.01.2016, 16:41
Hallo,

Bevor man Macro anstelle von inline Funktionen vorschlägt sollte man sich Gedanken drüber machen ob Macros wirklich Sinn machen.


Wenn man garantiert haben will, dass der Code auch wirklich inline eingefügt wird, geht das nur mit Macros.
Inline ist, wie vieles in C, nur eine Empfehlung an den Compiler.

Übrigens wurde inline erst mit C++ eingeführt und wurde dann in C99 übernommen.

MfG Peter(TOO)

shedepe
15.01.2016, 18:20
@Peter: Das stimmt so nicht. Wenn du dir den Thread noch mal durchliest, dann kann man tatsächlich den Compiler auch zu einem inline zwingen. Nur ist das eben compilerspezifisch und nicht im C/C++ Standard festgelegt.

Sisor
15.01.2016, 19:36
Microsoft hat nen ganz interessanten weiterführenden Artikel (https://msdn.microsoft.com/de-de/library/bw1hbe6y.aspx) zum Thema "inline" verfasst.

Siro
15.01.2016, 22:43
@Peter : Einige Teile kann ich tatsächlich mit einem MACRO realisieren
ich hatte auch gelesen, dass es erst ab C99 ein "inline" gibt

@Sisor: Viele Infos, hab ich mir auch grad angeschaut. Danke Dir

@shedepe: wenn ich das richtig gelesen habe, kann man nur versuchen den Compiler zu zwingen
z.B. mit __forceinline. entscheiden tut letztendlich aber der Compiler ob er es inline codiert.

Zumindest hab ich jetzt etwas dazugelernt, dass es sogenannte "Empfehlungen" für den Compiler gibt.
Das war mir völlig neu.

Ich Danke Euch nochmal allen für die Anteilnahme

Peter(TOO)
16.01.2016, 04:22
Hallo Siro,

Zumindest hab ich jetzt etwas dazugelernt, dass es sogenannte "Empfehlungen" für den Compiler gibt.
Das war mir völlig neu.

Es gab noch "register", auch eine Empfehlung an den Compiler.
Der Compiler sollte entsprechende Variablen dann eine auto-Variable in einem CPU ablegen und nicht auf dem Stack.
Dies optimiert aber ein heutiger Compiler selbst.

C ist eine super Sprache, zumindest wenn man weiss was man macht und auch was der Compiler macht. Und über den Linker bescheid zu wissen ist, zumindest auf µCs, auch noch eine Notwendigkeit.
Spannend wird es dann, wenn man Code für unterschiedliche CPU-Architekturen, und meist auch unterschiedliche Compiler, entwickelt, welcher portierbar sein soll ;-)

MfG Peter(TOO)

Siro
17.01.2016, 21:33
Register stammt glaube ich noch aus den 8 Bit Zeiten und wird heute wohl eher nicht mehr benutzt.

Was der Compiler für Code draus macht, gucke ich mir liebend gerne im Assemblercode an und nicht immer finde ich den Code gut ;)
Umgekehrt habe ich auch schon aus dem erzeugten Assembler Code vom Compiler gelernt. Da kamen dann solche Gedanken:
Ach das geht auch .....

Peter(TOO)
18.01.2016, 01:23
Hallo,

Register stammt glaube ich noch aus den 8 Bit Zeiten und wird heute wohl eher nicht mehr benutzt.

Eine 8-Bit-Zeit gab es bei C gar nie :-)

1970 gab es auch noch keine Mikroprozessoren. C unterstützte damals 8-, 9-, 12-, 16-, 18-, 32-, 36- und 48-Bit CPUs.

In den 1970er Jahren war die Computerwelt noch sehr Dezimal geprägt.

MfG Peter(TOO)