PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Durch inline kleinerer Code?



luma
09.06.2005, 18:39
Hio. Ich arbeit mich gerade von Java in C++ ein. Hab da gelernt, das eine Funktion die mit inline markiert ist:
a) Schneller ist beim ausführen aber dadurch
b) die Größe der compilierten Datei vergrößtet
Aber irgendwie werden bei mir die Dateien dadruch kleiner? Ich compilier mit avr-g++. Ohne inlines ist der Code etwa 2Kb groß, mit inlines etwa <1Kb...
Ist das normal?

cu
Luma

PicNick
09.06.2005, 18:59
Ganz allgemein kann man das Ergebnis nicht vorhersagen. Du kannst mit "inline" auch jederzeit einen Stiefel reinschreiben, der den kompletten Flash abfackelt.
Ich weiß nicht, ob der avr-g++ auch ein Disassembler listing hergibt. da könntest du vergleichen, was er macht, und was du in Assembler schreiben würdest.
das Verhältnis 2:1 ist schon ein bißchen viel, aber, wie gesagt, man müßt sich den Code anschauen.

luma
09.06.2005, 19:04
Wahh? Kann ich den meinen Bobby mit den falschen Befehlen schrotten?

PicNick
09.06.2005, 19:11
nein, nein, abfackeln heißt, alles verbrauchen.

luma
09.06.2005, 19:12
Uhi ich dachte schon. Ich glaub, dann würden sich bei mir die Dinger nur so stapeln ;D...

Edit: Ist den das Programm in dem AVR nicht auch so groß wie auf meinem Rechner? Und wenn nicht, woher weiß man das?

PicNick
09.06.2005, 20:40
Die Größe der Hex-File kannst du als Maßstab nehmen
Ich hab mich undeutlich ausgedrückt: Du kannst mit inline Assembler Platz sparen, wenn du geschickt bist, du kannst aber genausogut MEHR verbrauchen als der C, wenn du die Vorteile des Assembler nicht wirklich ausnützen kannst.
Wenn nicht wirklich notwendig ist, tät ich es aber lassen mit dem inline, weil damit ist der ganze Datenkapsel- Object- Klassengedanke irgendwo im Brunnen.
bis morgen, ich begebe mich zur Ruhe !

lekro
09.06.2005, 22:49
inline != inline assembler.

Das sind zwei paar Schuhe. Ich denke, der OP meinte das Schlüsselwort "inline", das man vor Funktionen schreiben kann.

Um diesen signifikanten Größenunterschied genauer erklären zu können, könnte etwas Quellcode aber nicht schaden.

Felix G
10.06.2005, 01:22
Also eine mit inline deklarierte Funktion in C wird vom Compiler quasi wie eine Art Makro* behandelt.
d.h. es wird kein Call-Befehl erzeugt, sondern der Funktionsrumpf einfach an die Stelle kopiert (dadurch größerer Code).

Für kleine Funktionen kann das sehr praktisch sein.


Aber:
nur weil inline vor der Funktion steht heisst das noch lange nicht, daß der Compiler sie dann auch wirklich inline macht!
Es ist also eher als eine Art "Empfehlung" zu verstehen.

Bei sehr grossen Funktionen wird der Compiler das inline ignorieren,
ebenso wird er bei sehr vielen kleinen inline-Funktionen nur einen Teil wirklich als inline behandeln.




*Im Gegensatz zu einem Makro ist es aber eine echte Funktion mit Typprüfung etc.

PicNick
10.06.2005, 07:48
Ahhhhhhhhh so !
verstehe ! Auch was dazugelernt !
Das ist so wie "register" oder das Götz-Zitat:
Eine Anheimstellung, der Folge zu leisten dem Angesprochenen frei steht

pebisoft
10.06.2005, 09:22
wenn du einmal den winavrc-hexcode im avr studio anschaust, kanst du sehen das dieser hex-code 99% eines assemblercodes ist. was willst du da noch optimieren???? inline-code bei winavr-c --- nein!!!
wenn du einmal den hexcode von bascom anschaust, kannst du festellen, das der wesentlich grösser ist und sehr grosszügig mit den routinen rumprotzt. inline-code bei bascom ---- ja!!!!
mfg pebisoft

FoCus
10.06.2005, 09:35
wenn du einmal den winavrc-hexcode im avr studio anschaust, kanst du sehen das dieser hex-code 99% eines assemblercodes ist.


Ähm kannst du mir ein Beispiel deiner restlichen 1% sagen!?
Bin eigentlich der Meinung dass das direkt in Maschinencode umgewandelt wird. Warum sollte da was wegfallen?



Aber irgendwie werden bei mir die Dateien dadruch kleiner?


Klar kann er dadurch kleiner werden. Da die Funktionen wie Makros direkt in den Code eingefügt werden, fallen eine Menge Befehle, die Für den Aufruf, bzw beim Aufräumen, einer Funktion nötig sind weg. Dadurch wird der Code kleiner.
Die Borland Hilfe sagt dazu:


C++-spezifische Schlüsselwörter

Syntax

inline <datentyp> <klasse>_<funktion> (<parameter>) { <anweisungen>;*}

Beschreibung

Das Schlüsselwort inline dient zum Deklarieren oder Definieren von C++ Inline-Funktionen.

Zu Inline-Funktionen macht man am besten nur kleine, sehr häufig aufgerufene Funktionen.


Allerdings ist ein Verhältnis von 2:1 schon recht heftig. Ein bisschen Code wäre klasse.


Gruss
Michael

OldBug
10.06.2005, 11:48
Die Größe der Hex-File kannst du als Maßstab nehmen


Das ist Falsch! Im .hex-File sind Angaben wie Adresse und Checksumme enthalten, deshalb ist das .hex-File wenig Aussagend, was die Größe im Flash betrifft. Im aktuellen WinAVR gibt es ein Script, welches die Auslastung des Memories durch statische Variablen und die des Flashs berechnet und Anzeigt.

PicNick
10.06.2005, 12:40
Das ist Falsch! Im .hex-File sind Angaben wie Adresse und Checksumme enthalten, deshalb ist das .hex-File wenig Aussagend, was die Größe im Flash betrifft
Was du nicht sagst.
Wenn du die Hex-files mal liest, wirst du sehen, daß alle Zeilen, außer der letzten (u. EOF), die größe 16 haben.
also filesize / 45 * 16 und ein paar zerquetschte, auf die wir aber pfeifen, weil's da um Programme geht und nicht um "Hello, world"
Wenn du die letzte adresse liest, kannst du es auch noch genauer sagen
Außerdem geht's hier um relative Vergleiche(standard, inline, optimizer, Compiler, etc) und dafür reicht's allemal.

luma
10.06.2005, 13:04
Also das ist komisch. Ich generier keine .HEX-Dateien sondern .BIN-Dateien...

PicNick
10.06.2005, 13:11
Na, noch besser. da hast du die Größe pur

SprinterSB
10.06.2005, 14:26
Zur Grösse: Bei WinAVR gibt's auch ein avr-size, das macht genau was ihr wollt ;-)

gcc 3.4.1 inlinet kleine Funktionen von selbst, auch grössere Funktionen werden geinlinet wenn sie nur 1x benutzt werden.
Ich compiliere mit -Os, und ein Blick auf den generierten asm-Code schadet nie...
Soll eine Funktion geinlinet werden, so kann das ein Kompiler nur dann gescheit machen, wenn sie als static deklariert ist. Daher ist es sinnvoll, die direkt im Header zu deklarieren, wenn sie in mehreren Modulen benutzt werden soll.
Eine Funktion als extern inline zu deklarieren ist nicht sinnvoll, denn der Compiler kann den Code einer solchen Funktion nicht kennen (es sei denn, er steht im gerade compilerten Modul).

Damit Funktionen, die inline stehen, nicht nochmal im .o auftauchen, gibt es den Schalter -fno-keep-inline-functions
Wird eine Funktion nicht geinlinet, obwohl man das will, warnt gcc bei -Winline.
inline generell deaktivierten sollte mit -fno-inline gehen und für eine Funktion mit __attribute__((noinline))

gcc hat übrigens eigene Kriterien, um zu entscheiden, ob eine Funktion es "wert" ist, geinlinet zu werden, so daß inline bzw __attribute__ ((inline)) nicht immer greifen. Drehen kann man an dieser Entscheidung mittels -finline-limit=<n>

Gruß, Johann

luma
10.06.2005, 19:23
Aha und wie mach ich ne .hex??

pebisoft
11.06.2005, 12:48
focus , schau dir die beispiele in winavr-c an, die als avrlibc-manual beiliegen, sind schöne vergleich drin. c++ verschwendet auch teilweise den asm-code. winavr-c ist kein c++.
mfg pebisoft

lekro
11.06.2005, 21:21
c++ verschwendet auch teilweise den asm-code.Immer diese Vorurteile...
Prinzipiell ist kompilierter C++-Code erstmal nicht größer als gleichwertiger C-Code.

winavr-c ist kein c++.Den Satz versteh ich nicht ganz. Natürlich ist "C" kein "C++". Aber C ist C, "winavr-C" gibt es in dem Sinne überhaupt nicht.

Man kann mit WinAVR auch C++ kompilieren (siehe FAQ, mal von einigen Einschränkungen und der fehlenden Standardbibliothek abgesehen).

pebisoft
11.06.2005, 22:45
man sollte dieses gute winavr-c nicht durch eingebaute c++ schnitzel versauen. ihr interpretiert in winavrc immer sachen hinein, da staune ich nur.
winavrc ist ein ganz normales standart c , da gibt es kein wenn und aber.
mfg pebisoft

lekro
11.06.2005, 23:22
Hast du schonmal versucht C++-Code zu kompilieren oder vermutest du nur, dass C++ größeren Code erzeugt?


winavrc ist ein ganz normales standart c , da gibt es kein wenn und aber.Nichts anderes habe ich vorhin behauptet. WinAVR beinhaltet jedoch neben dem Standard-C-Compiler auch noch einen C++-Compiler (der allerdings nicht standardkonform ist).


btw, "Standard" :) (nichts für Ungut).

luma
12.06.2005, 17:27
Hu. Kann mir den jemand diese Fragen noch beantworten...

a) Woher weiß ich, wie groß das Progrämmchen für den Bot im Speicher sein wird? (Genau so groß wie auf meiner Festplatte?)
b) Vielleicht ein kleiner Hinweis wie ich ne hex hinbekomm...

luma
12.06.2005, 19:31
Hio. Ich hab jetzt bissel rumgespielt und endlich ne hex-Datei bekommen. Nur ist die irgendwie (im Vergleich zur bin-Datei) riesig?! Ganze 4,6KB für 'n paar Zeilen Code. (Bevor die Frage kommt:Code Stammt von www.qfix.de und dient zum Testen des Crash-Bobby. Dort ISO-Datei runterladen, dann brennen oder als virtuelles Laufwerk einrichten und man hat den Code. Ist aus dem Ordner bobbyTest (/software/bobbyTest).). Ich erzeuge die hex dann so...

Ich hab die BAT-Datei (die auch im Ordner bobbyTest ist) ein bisschen modifiziert und zwar so:

@echo off
set TARGET=Shadowstriker
set CONTROLLER=atmega32
set INCLUDE=../include

<nul (set/p z=Clean... )
if exist %TARGET%.bin del %TARGET%.bin
echo OK

<nul (set/p z=Build... )
avr-g++ -c -o %TARGET%.o -g -O2 -Wall -I%INCLUDE% -mmcu=%CONTROLLER% %TARGET%.cpp
avr-g++ -g -Wall -O2 -mmcu=%CONTROLLER% -o %TARGET%.elf %TARGET%.o
avr-objcopy -j .text -j .data -O binary %TARGET%.elf %TARGET%.bin
echo OK

:End


Das kommt also alles in ne BAT-Datei rein und wird mit der Console (cmd.exe) ausgeführt. Danach findet man nen haufen Dateien in dem Ordner aus welchem die BAT-Datei aufgerufen wurde, wenn alles geklappt hat. Und dann ruf ich mein Makefile auf. Das erzeugt dann die Hex... Und die ist (im Vergleich zur produzierten BIN-Datei die man ja auch auf den Bobby laden kann) extrem groß. Was mach ich falsch??


Grüße
Lutz

OldBug
12.06.2005, 20:58
Die Antowrt hatte ich bereits gegeben, aber offensichtlich war die "Elite" hier davon überzeugt, daß ein "Anhaltspunkt" alles notwendige aussagt... Na was solls...

luma
13.06.2005, 14:20
Hio. Also ich hab jetzt nochmal ne HEX erstellt und das avr-size (ich hoffe das ist das besagt Script, oder der Aufruf davon) aufgerufen und folgendes Ergebnis erhalten:
...
hex 689 ....
...
(Mehr siehe Bild im Anhang. Drüber sieht man auch noch das Ergebnis des make-Aufrufs). Heißt das jetzt die HEX-Datei ist 689 Bytes, Bits (ne Einheit wäre schön :)), oder was?

Grüße
Lutz

PicNick
13.06.2005, 14:53
Die Programmgröße ist "hexadezimal" 689
dezimal sind das 1688 Bytes. Im Konsolenfenster siehst du's ja
Als Hex-File braucht er dafür 4780 Bytes (properties)

OldBug
13.06.2005, 15:45
AVR Memory Usage:
-----------------
Device: attiny26

Program: 2636 bytes (128.7% Full)
(.text + .data + .bootloader)

Data: 0 bytes (0.0% Full)
(.data + .bss + .noinit)



...das mein ich!

Mit aktuellem Makefile auch ohne rebuild mit "make sizeafter" auf den Bildschirm zu zaubern ;)

bluebrother
13.06.2005, 19:31
a) Woher weiß ich, wie groß das Progrämmchen für den Bot im Speicher sein wird? (Genau so groß wie auf meiner Festplatte?)

also bei meiner Linux-Toolchain gibts ein »avr-size«. Dürfte unter Windows auch so heißen (ok, avr-size.exe ;-)



b) Vielleicht ein kleiner Hinweis wie ich ne hex hinbekomm...


wenn mich mein Gedächtnis nicht gerade trügt ging das mit mfile resp. dem Makefile. Hab grad kein winavr-Projekt da, sonst könnte ich kurz nachgucken ...

Argl! Übersehen dass da noch / schon Antworten waren ... na ja, still for the record.

luma
13.06.2005, 20:00
Hio. Also mir ist das jetzt nicht so klar...

1.Wenn ich in der Console “make sizeafter” eingebe kommt zwar ein Output, aber der sieht ganz anders aus, als der von OldBug . Siehe dazu Bild make_sizeafter.jpg. Was mach ich den Falsch?? (Warum zeigt die Console immer nur Blablabla.elf an? Ich will doch aber Blablabla.hex. Ich bin an jeglichem Versuch gescheitert make sizeafter die HEX zu übergeben)...
2.Nach dem Output von a.jpg müsst das Programm ja dann (9326 / 1048 ) ca. 8,9 kB Speicher fressen!? Kann das sein??
3.Ich glaub ich mach da ja selber irgendwo nen Fehler. Ich ruf ja immer die BAT-Datei vor dem make auf. Die erzeugt mir dann Dateien, die von make benötigt werden. Erst dann ruf ich die Makedatei auf. Ist das vielleicht falsch?? Schauht euch doch bitte die beiden Dateien nochma an (ein paar Postings höher in Dateien.zip)...
4.Einfach so zum Test bin ich mal in den WinAVR\examples\demo-Ordner gegangen. Hab dann in der Console make aufgerufen. Es gab dann auch schön ne HEX-Datei. Beim Versuch make sizeafter aufzurufen gab's folgende Meldung: „make: *** No rule to make target 'sizeafter'. Stop“. Liegt das vielleicht daran, dass das Makefile sich ziemlich vom meinem (ich hab das Standardmakefile vom MFile verwendet und bissel modifiziert) unterscheidet??

Wenn ihr ganz nett sein wollt und einem verzeifeltem Schüler helfen wollt, dann schreibt mir doch einfach ne Liste, wo alles drin steht, was ich wie wo und wann tun soll. :D Danke! Ambesten wäre natürlich Beispielcode und dann könnt ma nen kleines Tut machen und das im Forum posten und niemand wird die Frage mehr stellen :)...

Grüße
Lutz

luma
14.06.2005, 18:31
Weiß den niemand bescheid?

luma
16.06.2005, 18:06
Hio. Also ich habe das Problem jetzt selber gelöst...

Das (von mir gesuchte) Tool nennt sich nicht „avr-size“ sondern „avr-sizex“. Dieses gibt u.a. die Belastung des Flash et cetera in % sowie in Bytes an....

Nach einigen Tests hab ich herrausgefunden: Kleine C-Funktionen mit inline zu deklarieren kann richtig Platz schaffen (bei mir von 9 % auf 6 %). Ebenso das verweden von short-Variablen anstatt int (etwa 2 %). Man darf natürlich nur dann short-Variablen nehmen, wenn keine großen Zahlenwerte speichern will...


Cheers
Lutz


P.S.: Bevor jetzt jemand sagt, ja toll die erwähnten 2-3 % sind ja fast gar nichts: Mein Programm ist vom Umfang her noch ziemlich klein. Wenn das mal wächst machen sich die Einsparungen auf jeden fall bemerkt.

FoCus
20.06.2005, 15:22
focus , schau dir die beispiele in winavr-c an, die als avrlibc-manual beiliegen, sind schöne vergleich drin. c++ verschwendet auch teilweise den asm-code. winavr-c ist kein c++.
mfg pebisoft

Du hast von Winavr-Hexcode gesprochen, nicht von c!
bei c stimme ich dir zu, hab ich auch garnicht angezweifelt, aber ich denke kaum das Winavr-Hexcode nicht 1:1 umgesetzt wird.

Gruss
Michael