mikrocontroller.net

Forum: Compiler & IDEs WinAVR 20080402


Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag allerseits

Ich habe mir soeben die neueste WinAVR installiert; nur passt nun das 
Programm nicht mehr ins Flash. Waehrend es vorher (mit WinAVR-20071221) 
zu 98% voll war, sind es nun 108%.
Wie ich gelesen habe, gibt es eine neue Optimierungs-Stufe 
-fwhole-program, die beim Linken aufgerufen wird. Ich habe dies im 
makefile, das AVR-Studio erzeugt, eingefügt; aber ohne Erfolg.
Habe ich sonst noch was übersehen?

Mfg aus Istanbul

Autor: Nixiefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
auch wenn ich jetzt Prügel bekomme, aber in dieser Beziehung ist der 
aktuelle Compiler einfach Schei....

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe zuwenig Kenntnisse in Sachen Compilerbau, als dass ich jetzt 
darüber eine Meinung abgeben könnte, ob jetzt Sch... oder nicht.
Aber als GCC-User sollte es unsere Pflicht sein, sobald als möglich auf 
die neuste Version umzusatteln und über mögliche Fehler zu berichten.

Autor: Jupp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Aber als GCC-User sollte es unsere Pflicht sein, sobald als möglich auf
>die neuste Version umzusatteln

Sehe ich nicht so, denn das Umsatteln bringt eigentlich immer Probleme 
mit sich. Hoch lebe der Frickler...

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Natürlich gibt's Probleme. Aber wie sollen diese Probleme behoben 
werden, wenn diese nicht gemeldet werden?

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sage ja nicht, du sollst in einer laufenden Entwicklung auf die neue 
Version umsteigen. Aber eine abgeschlossene Entwicklung sollte man schon 
zu Testzwecken durch den neuen Compiler jagen.
Und eine Neuentwicklung, die z.Zt. bei mir ansteht, würde ich schon 
gerne mit der neuen Version beginnen.

Autor: Nixiefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So weit ich das verstanden habe, liegt bei der GCC Entwicklung der Fokus 
nicht auf minimaler Codegröße für 8-Bit AVRs, so das aus dieser Sicht 
der Compiler wohl immer schlechter werden wird...

Autor: Robin Tönniges (rotoe) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte mir auch den neuen Compiler geholt und das Programm wurde
1. Größer
und
2. Funktionierte es nicht mehr.

Deshalb bin ich wieder auf die ältere Version umgestiegen.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab hier mal eine Routine rausgepickt, die von 9 auf 21 Words 
angestiegen ist, also nur auf schlappe 233%:

http://www.avrfreaks.net/index.php?name=PNphpBB2&f...

Das komplette Programm ist um 20% größer geworden, was ja auch schon 
ganz schön happig ist. Er hat also nicht alle Routinen derartig 
drastisch unoptimiert.

Obs noch läuft habe ich nicht testen können, die 120% passen nicht mehr 
in den Chip.


Peter

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mehmet Kendi wrote:
> Aber als GCC-User sollte es unsere Pflicht sein, sobald als möglich auf
> die neuste Version umzusatteln und über mögliche Fehler zu berichten.

Ich sage in solchen Fällen immer: "Hanemann, geh du voran!"

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab jetzt mal einen grösseren Chip gewaehlt und das Programm damit 
compiliert: die Schaltung funktioniert einwandfrei.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mehmet Kendi wrote:
> Ich hab jetzt mal einen grösseren Chip gewaehlt

Na dann schmeiß ich mal sofort den ATtiny45 runter und setzt nen 3GHz 
Quadcore drauf :-)
Hauptsache ich kann den neuesten Compiler benutzen, egal was es kostet.


Peter

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:D Peter, nicht gleich das Kind mit dem Bad ausschütten.
Wegen dieser Code-Vergrösserung bin ich nolens volens gezwungen, den 
alten Compiler zu benutzen.
Aber bei einem neuen Projekt, da macht es mir nichts aus, einen 
grösseren Chip zu waehlen.
Zumindest gehe ich davon aus, dass dieses Mehr an Code zugunsten von 
mehr Sicherheit erkauft wird. Nur so 'ne Vermutung.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Interessant wäre es, mal zu wissen, was der neue konkret besser können 
soll.

Gibt es denn irgendwelche richtig harten Bugs in dem alten?

Wenn es nur um den ATXmega Support geht, dann brauche ich den neuen 
nicht.

Ulkiger Weise scheint der XMega aber auch keine Hardwaredivision zu 
haben, da ist der Hang zum unnötigen Divisionsaufruf ziemlich 
unverständlich.

Ich denke mal, es ist schon opportun, von nem neuen eine Verbesserung zu 
erwarten und keine Verschlechterung.

Allein nur, weil etwas neu ist, mach ich doch keinen Handstand.



Peter

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im WinAVR User Manual 20080402 steht u.a.

"GNU Compiler Collection (GCC) 4.3.0 Release Candidate 20080301"

Ist er noch nicht fertig !!!!! Folgt balb schon wieder eine neue Version 
mit dem GCC 4.3.0 Final ??? Wird dieser dann wieder weniger Code 
erzeugen ???

Fragen über Fragen

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter
Ich pflichte Dir bei. Aber. Wenn keiner den neuen Compiler testet, wie 
in aller Welt sollen dann die Entwickler auf die möglichen Fehler 
aufmerksam werden? Dann könnte man ja die ganze avr-gcc Entwicklung 
beenden und sagen "der aktuelle Compiler tut's ja".

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mehmet Kendi wrote:
> @Peter
> Ich pflichte Dir bei. Aber. Wenn keiner den neuen Compiler testet, wie
> in aller Welt sollen dann die Entwickler auf die möglichen Fehler
> aufmerksam werden?

Naja, er macht ja keinen Fehler. Er macht es nur umständlicher, mit viel 
mehr Code und Zeitbedarf als nötig.
Solche Sachen, die nicht dem ANSI-C widersprechen haben kaum Chancen.

Auch tue ich mich schwer, in diesem Sourceforke durchzusehen, wie und wo 
man Probleme richtig reinstellt (ein Wiki oder Tutorial dafür wäre nicht 
schlecht).

Wenn ich merke, ein Compiler erzeugt falschen Code, dann würde ich das 
natürlich sagen und versuchen, ne andere Version zu finden, die den 
Fehler nicht mehr bzw. noch nicht macht.

Wenn aber der Code nur langsamer und größer wird, dann kann ich nur 
versuchen die optimale Version zu finden.

Der WINAVR-20071221 macht auch vieles nicht mehr so gut, wie der 
WinAVR-20070122.
Aber er hat kann MOVW bei den ATtinys und damit ist dann in der Summe 
der Code doch kleiner und schneller, da ich fast nur ATTinys einsetze.

Ich hab ein neues Projekt mit dem ATmega168 und da werde ich 
warscheinlich mit dem WinAVR-20070122 am besten fahren.

Ich hab mir extra ein paar Batch-Dateien geschrieben, mit denen ich 
schnell zwischen den Versionen umschalten kann.


Peter

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:

> Ich hab hier mal eine Routine rausgepickt, die von 9 auf 21 Words
> angestiegen ist, also nur auf schlappe 233%:
>
> http://www.avrfreaks.net/index.php?name=PNphpBB2&f...

Eigentlich ist der neue Compiler genial, denn er erkennt, dass die
Schleife nichts weiter tut, als aus zwei Zahlen Quotient und Rest zu
berechnen. Auf Prozessoren mit Hardwaredivision oder bei einer
größeren Anzahl von Schleifendurchläufen ist es auch völlig richtig,
die fortgesetzte Subtraktion durch eine Division zu ersetzen.

Leider hat der Compiler keine Sonderbehandlung für den AVR eingebaut,
für den die Division natürlich kein Pappenstiel ist.

Unglücklicherweise führt er die Division sogar zweimal durch, nämlich
erst für den Quotienten und dann für den Rest, obwohl die
Divisionsroutine beides auf einmal liefern würde.

Die Bibliotheksdivision führt zur den 12 zusätzlich Codeworten, aber
auch nur dann, wenn sie nicht sowieso schon an anderer Stelle im
Programm benötigt wird.

Der GCC wäre aber nicht der GCC, wenn man das unglückliche Feature -
wie auch die meisten anderen Optimierungen - nicht selektiv abschalten
könnte, und zwar mit

  -fno-tree-scev-cprop

Mit dieser Option wird die Codegröße des Beispiels wieder auf die
ursprünglichen 9 Worte reduziert. Ob damit an anderer Stelle Nachteile
entstehen, weiß ich nicht, da ich auf die Schnelle keine detailierte
Beschreibung der Option gefunden habe.

Wie Nixiefan oben schrieb, ist der GCC nicht primär für 8-Bit-
Prozessoren in speicherarmen Umgebungen gemacht. Wenn man jedes Byte
und jeden Taktzyklus zählen muss, ist es wichtig, mit den richtigen
Compiler-Optionen zu arbeiten. Die Defaulteinstellungen sind eher für
32-Bit-Prozessoren mit üppigem Befehlssatz und massig Speicher
geeignet. Handbuch lesen hilft oft, wenn auch nicht in diesem
speziellen Beispiel. Aber wo das Handbuch aufhört, fängt Google an ;-)

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
yalu wrote:
>
>   -fno-tree-scev-cprop
>
Staun! Also ich habe mal mit Google gesucht, habe nicht eine Erklärung 
zu der Option gefunden. Nur Funde im Zusammenhang mit einem Linux Kernel 
Bug.
Auch das GCC Handbuch danach durchsucht. Nichts.

Woher wußtest Du von dieser Option und dass sie das bewirkt?

900ss

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
avr-gcc --help=optimizer

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Staun! Also ich habe mal mit Google gesucht, habe nicht eine
> Erklärung zu der Option gefunden. Nur Funde im Zusammenhang mit
> einem Linux Kernel Bug.

Die Linuxer sind wohl neben Peter die einzigen, die das Problem bisher
wahrgenommen haben. Ich bin auf die Diskussionen gestoßen, nachdem ich
im GCC-Manual vergeblich nach einer passenden Option gesucht und
deswegen angefangen habe, Google mit dem Problem zu beschäftigen.

Ich habe die Diskussion nicht im Detail durchgelesen, aber es geht
wohl um eine Rechenoperation, bei der eine Zeit in Nanosekunden (64
Bit!) zu einem struct timespec (Sekunden und Nanosekunden) addiert
wird. Damit das Ergebnis gleich normiert ist, werden die Nanosekunden
in 10E9er-Schritten addiert. Da der Prozessor keine des
64-Bit-Division kann und typische Zeitwerte selten größer als 1 s
sind, wird im C-Code auf Divisionen absichtlich verzichtet. Der GCC
4.3.0 baut aber genau diese wieder ein. Das Problem ist also fast das
gleiche wie das von Peter.

Folge dieser Diskussion: Die GCC-Entwickler sind sich des Problems
bewusst. Man darf gespannt sein, wie das Problem in künftigen
GCC-Versionen gehandhabt wird. Da es sich bei der Optimierung um
keinen Fehler handelt und in vielen Fällen tatsächlich eine
Verbesserung des erzeugten Codes stattfindet, wird man sie sicher
nicht entfernen.

Gerade habe ich noch eine Möglichkeit gefunden, den Tatendrang des
Compilers nur lokal zu bremsen: Man fügt eine Optimierungsbarriere in
Form einer __asm__-Anweisung wie folgt in die Schleife ein:
  for( tens = 0; val >= 10; val -= 10 ) {
    __asm__ ("" : "=r" (val) : "0" (val));
    tens++;
  }

Damit wird die Schleife gleich übersetzt wie mit -fno-tree-scev-cprop,
lässt die Optimierung aber an anderer Stelle trotzdem zu.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber das bringt's nicht wirklich. Oder ist nur ein Problem von mehreren.

Mir hat es von 20070525 zu 20080404 Release den Code von 3424 auf 3614 
Bytes aufgeblasen. Grund dafür ist ein -Os völlig zuwiderlaufendes 
agressives Inlining. Ein häufig auftretender Funktionsaufruf (4 Bytes) 
wurde durch jeweils 16 Bytes ersetzt.

Mit -fno-inline-small-functions (kann auch mal nach hinten losgehen) 
oder -finline-limit=<n> (hier ist ggf. etwas tuning angesagt) hält man 
sich das vom Leib. Ergebnis: 3196 Bytes.

Ähnliches ist mir schon früher in der ARM Version passiert. Die hinter 
diesem Inlining stehende Grössenabschätzung ist wohl "etwas" unpräzise.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger wrote:

> Interessant wäre es, mal zu wissen, was der neue konkret besser können
> soll.

Die Benutzung von GCC 4.3 war für Eric die einzige Chance, dass er
den Xmega-Support mit reinbekommen konnte, weil dieser nur für diese
Version gezimmert worden ist (und letztlich immer noch wird -- da ist
doch manches anders dabei als bei den alten Cores).  Das Rückportieren
dieses umfangreichen Patchwerkes auf die 4.2-er Linie war schon aus
Gründen fehlender Manpower nicht machbar.

Idealerweise hätte er wohl Installationsoptionen für GCC 4.2.x ohne
Xmega-Support und 4.3-BETA mit Xmega anbieten sollen, aber dafür fehlt
es ihm im WinAVR-Installer an jeglicher Unterstützung für derartige
Optionen.  Das wäre übrigens ein Feld, wo sich ein ambitionierter
Windows-Entwickler ganz sicher in diesem Opensource-Projekt einbringen
könnte: den Installer flexibler zu machen.  Ist ja nicht das erste
Mal, dass man sich sowas gewünscht hätte.  Installationsoptionen
wären beispielsweise auch denkbar, um dem Nutzer wahlweise die
Installation eines Standalone-USB-Treibers oder des Filter-Treibers
(der oberhalb des Jungo-Treibers von AVR Studio sitzt) zu ermöglichen.

> Ulkiger Weise scheint der XMega aber auch keine Hardwaredivision zu
> haben,

Nö, die Änderungen im XMega sind an anderen Stellen.  Na komm, du hast
selbst jahrelang nach priorisierbaren Interrupts gerufen...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sehr schöne Antworten, hat sich also voll bezahlt gemacht, das konkrete 
Problem zu posten.
Das mit dem unerwünschten Inlining hat mich auch schon immer gestört.
Diese Optimierungsschalter sind aber wohl erst mit GCC 4.3. anwendbar.

Allerdings krieg ich nun Probleme mit der Kommandozeile, die wird zu 
lang.
Weiß da einer vielleicht Abhilfe?

Kann man irgendeine Datei editieren, wo sich der GCC die 
Optimierungseinstellungen rausholt?


Peter

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
-finline-limit=<n> existiert schon länger.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger wrote:

> Kann man irgendeine Datei editieren, wo sich der GCC die
> Optimierungseinstellungen rausholt?

Der Klassiker: @file

Steht übrigens im Manual ;-).

Autor: Peter Dannegger (peda)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So, die beiden Optimierungen haben voll eingeschlagen (14% weniger), ist 
schon fast wieder an den GCC4.2.2 ran.

Ich hab dann mal gesucht, wo der nächste Codefresser sitzt und ihn 
gefunden.

Vielleicht findet ja noch jemand raus, warum darin der GCC4.3.0 
haufenweise unnütz pusht, moved, ored.
Da scheint irgendwas in der 32-Bit Berechnung umständlich zu laufen.
Die Routine steigt damit um 155% an.

Anbei der Quellcode und die beiden Listings.


Peter

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
-fno-split-wide-types

... und wieder 10 Bytes weniger bei mir.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Kaiser wrote:
> -fno-split-wide-types
>
> ... und wieder 10 Bytes weniger bei mir.

Bei mir 54 Bytes weniger und damit ist er endlich kleiner als der 4.2.2


Peter

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schreibt bitte bugreports für sowas, mit nachvollziehbaren
Codeschnipseln.  Das ist die einzige Hilfe, wie die GCC-Entwickler
derartige Tuning-Geschichten dauerhaft reparieren können.

Autor: die ??? (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal eine blöde Frage: Warum werden solch offensichtlichen Flags nicht 
automatisch mit dem MCU Typ ausgewählt? Wozu heißt es AVR-GCC?

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die ??? wrote:

> Mal eine blöde Frage: Warum werden solch offensichtlichen Flags nicht
> automatisch mit dem MCU Typ ausgewählt?

Weil sie nicht offensichtlich sind.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Kaiser wrote:

> Weil sie nicht offensichtlich sind.

Genau darum sollst du auch einen Bugreport schreiben, damit Dinge,
die nun plötzlich offensichtlich zu sein scheinen, künftig einfach
mal schon standardmäßig aktiviert werden können.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auf einen Tag kommt es dabei nun auch nicht an, also Geduld.

Das war ja meinerseits eine Antwort auf ??? Ich hoffe dass ich Peters 
Code legal dafür verwenden darf, sonst muss er's selber machen.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Kaiser wrote:
> Das war ja meinerseits eine Antwort auf ??? Ich hoffe dass ich Peters
> Code legal dafür verwenden darf, sonst muss er's selber machen.

Kannste nehmen.


Peter

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also bei mir haben diese Flags nur zu einer 0,3 prozentigen Reduzierung 
geführt.
Mit WinAVR-20071221 98%
mit 20080402 ohne irgendwelche Flags: 108,3%
mit den Flags -fno-tree-scev-cprop und/oder -fno-split-wide-types 108%

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat keiner behauptet, dass die Suche zu Ende sei. Wirf mal einen Blick 
in die Mapfiles und stelle fest, ob eine bestimmte Funktion besonders 
gross wurde.

Und probier dann besser gleich mit
  avr-gcc -Os -fno-<hier-die-option-reinschreiben> quelle.c
mal aus, ob sich unter den in -O1 oder -Os verwendeten 
Optimierungsoptionen was passendes findet.

PS: Du hast -fno-inline-small-functions vergessen.

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mit -fno-inline-small-functions: 107,6%  :)
Das map-file muss ich erst mal analysieren.

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich habe das ganze mit den verschiedenen genannten Optionen (auch 
noch andere) mit einem Bootloader probiert, der aus 2 Funktionen besteht 
(main + nochwas, startup-libs u.s.w. fehlt). Ist komplett in C 
geschrieben. Da hat der WinAVR-200705xx (die Version vor 
WinAVR-20071221) etwas unter 1024 Bytes erzeugt. Das Minimum mit dem 
aktuellen WinAVR war 1056 Byte. Ich meine bei 2 Funktionen kann man auch 
nicht viel mit Inlining optimieren :-) -fno-tree-scev-cprop und 
-fwhole-program haben am meisten gebracht. Allerdings komme ich eben 
nicht unter die 1024 Byte. Und das ist für einen Bootloader dann 
schlecht, da dann man gleich weitere 1Kb Flash opfern muß. Vielleicht 
hat ja noch jemand eine Idee.  ????

Habe schon einige Optionen probiert, komme aber nicht unter 1024 Bytes. 
Hier zeigt sich, das man auch keine pauschalen Aussagen machen kann, wie 
gut ein Optimierungsswitch wirkt. Kommt immer noch ein wenig auf den 
Code an.

Viel Spaß noch,
900ss

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich hab' mal beide map files durchgesehen. Von dem, was auf meinem 
Mist gewachsen ist, gibt es ein Mehr von nur 82 Bytes.
Der Rest von ca. 150 Bytes geht auf das Konto von GCC 4.3

Besonders sticht ins Auge, dass 4.3.0 _prologue_saves_ und 
_epilog_restores_ hinzugefuegt hat. Diese scheint er beim 
eeprom_read_block() hinzugefügt zu haben.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn diese Funktionen sowieso drin sind, kannst du sie genausogut auch 
benutzen. Es gibt eine AVR-spezifische Option, mit der die 
push/pop-Orgien an Anfang und Ende von Funktionen teilweise per 
Laufzeitfunktion erledigt werden. Hab bloss den Namen grad nicht parat.

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naked?

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
-mcall-prologues

Möglicherweise wurde der eeprom-Kram in der Lib damit übersetzt.

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Damit bin ich auf 103,1% runter :)
.... aber die Push&Pop Orgie ist immer noch da. Und zwar wird diese 
innerhalb von __eerd_block aufgerufen, das wiederum von 
eeprom_read_block aufgerufen wird.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo genau ist die push/pop-Orgie? In der EEPROM-Lib oder separat in Form 
der prolog/epilog-Funktionen? Letzteres ist klar, denn diese Funktionen 
sind die Grundlage von -mcall-prologues.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Kaiser wrote:

> Möglicherweise wurde der eeprom-Kram in der Lib damit übersetzt.

Ja, der eeprom-Kram wird nun inline gemacht statt über Bibliotheks-
funktionen (war die einzige Möglichkeit, ohne komplettes Umstruktu-
rieren von AVR-GCC und avr-libc die EEPROM-Routinen für jeden
AVR-Typ customized zu bekommen), und Eric hat sich für die
call-prolog-Variante entschieden.  Warum?  Ich denke, dass das
WinAVR-Template das ohnehin als Default hat, weil es normalerweise
Platz spart (geringfügig auf Kosten der Ausführungszeit).

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ähm... wenn diese Funktionen inlined sind, sollte es doch eigentlich 
dadurch überhaupt keine Lib-induzierten prolog/epilog-Funktionen geben?

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Separat in Form der prolog/epilog-Funktionen.
Aber auch ohne -mcall-prologues habe ich diese Funktionen, die meiner 
Meinung nach das ganze so aufblaehen.

Wenn ich das Ganze mit 4.2.2 uebersetze, ist die Lib-Funktion 
eeprom_read_block ganze 13 Bytes.

Mit 4.3.0: 34 Bytes (__eerd_block) + (29 Bytes) prolog_save + (29 Bytes) 
prolog_restore

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist dieser Zuwachs arg störend? Diese Sorte Wachstum skaliert nicht, 
d.h. das vergössert den Code nicht prozentual. Die Einsparung durch 
-mcall-prologues hingegen erspart prozentual. Unterm Strich bist du also 
bei Tinys gekniffen und beim Mega644 klar im Vorteil.

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
".... Tinys gekniffen und beim Mega644  klar im Vorteil." :D
z.Zt. bin ich der Gekniffene: Mein Zeilprozessor ist ein 2333.

Naja, nicht so schlimm. Bleibe ich halt bei diesem eh alten Project beim 
4.2.2
Zumindest bin ich dahingehend beruhigt, dass dieses Mehr an Code einen 
Sinn hat.
Danke für die Hilfe.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der WinAVR-20080407 ist da.


Peter

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Benachrichtigung.
Aber der Compiler und AVR-LibC sind immer noch dieselben. Keine Ahnung 
was sich geaendert hat.

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Grund für die Neuauflage scheint hier zu liegen:
http://www.avrfreaks.net/index.php?name=PNphpBB2&f...

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mehmet Kendi wrote:

> Der Grund für die Neuauflage scheint hier zu liegen:

Ja.

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe jetzt mal
#include <avr/eeprom.h>
ausgeklammert und meine eigene eeprom_read_block funktion geschrieben:
Programmgrösse ist wieder wie bei 4.2.2 auf 98% zurück.

Autor: Robin Tönniges (rotoe) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So jetzt habe ich mir auch die neue Version geholt und keine Warnings 
(schonmal gut). Aber ein ganz bestimmter Teil meines Programms 
funktioniert nicht mehr.
Timer1a = (153 * Timer1) / 1000;

Hat vorher super funktioniert.

Beispiel:
Timer1 = 9968
Timer1a = (153 * 9968) / 1000;
Da kommt bei mir 1525,104 raus.
Er sagt 17.

Kann ich nicht nachvollziehen.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie sind die Datentypen definiert (also von Timer1)? Das Verhalten von 
Arithmetik bei Überlauf ist nur für Datentypen ohne Vorzeichen als 
Modulo-Arithmetik definiert. Bei Typen mit Vorzeichen ist es 
ausdrücklich undefiniert.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Robin Tönniges wrote:

> Da kommt bei mir 1525,104 raus.
> Er sagt 17.

Bei mir kommt 17 raus.

153 * 9968 sind 1525104 oder 0x174570.  Da die Rechnung im int-Bereich
gemacht wird (mehr hast du zumindest nicht angegeben), bleiben davon
nur die unteren 16 Bits übrig: 0x4570 = 17776.  17776 / 100 = 17.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Unter der Annahme, dass Timer1 uint16_t ist:
153 * 9968 = 17776.
17776 / 1000 = 17.

Autor: Robin Tönniges (rotoe) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also alle Variablen sind als uint16_t deklariert.

Aber wie mache ich dass er rechnet wie ich?

Hat sich erledigt habs gecheckt^^
Danke

Autor: Robin Tönniges (rotoe) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zu früh gefreut :(
Selbst mit "uint64_t Timer1a" zeigt er noch nicht an was ich will.
Was mich wundert ist, dass es bei dem alten Compiler funktioniert hat.
Aber auf den alten umsteigen möchte ich auch nicht.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klassischer Irrtum. Bei
  int b, c;
  a = b * c;
wird unabhängig vom Typ von "a" immer mit "int" gerechnet.

Du musst Timer1 breiter machen, nicht Timer1a. Oder
Timer1a = (153L * Timer1) / 1000;
rechnen.

Autor: Robin Tönniges (rotoe) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachdem ich Timer1 auf uint64_t erhöht habe funktionierts. Ich verstehe 
nur nicht warum?
In Timer1 wird doch nur ein 16 Bit Wert abgespeichert nämlich der von 
Timer1.
???

P.S.: Das mit dem 153L ändert nichts.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
153 ist vom Typ "int". Timer1 ist vom vom Typ "uint16_t=unsigned". Das 
Ergebnis der Multiplikation ist folglich vom Type "unsigned", und der 
geht bei AVRs nur bis 65535.

Auf einer 32bit Kiste sähe das anders aus.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Robin Tönniges wrote:

> P.S.: Das mit dem 153L ändert nichts.

Das finde ich jetzt interessanter. Und was ist bei
  Timer1a = (153 * (long)Timer1) / 1000;

Autor: Robin Tönniges (rotoe) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geht net. Also weder wenn ich das mit uint16_t Timer1 noch uint64_t 
Timer1 ausprobiere.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uint64_t ist übrigens weit übers Ziel hinaus geschossen.

(153ul * timer1) / 1000

sollte aber gehen.  Es zwingt den Compiler, timer1 von unsigned auf
unsigned long zu erweitern und entsprechend die Multiplikation für
2 unsinged longs zu generieren (die vermutlich in einer Funktion der
libgcc.a versteckt ist).

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jo, aber ob nun 153L oder 153uL, es sollte in beiden Fällen 
funktionieren, denn das Ergebnis passt sowohl in long als auch in 
unsigned long.

Autor: Robin Tönniges (rotoe) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab jetzt beides ausprobiert. Und bis jetzt ist uint64_t das einziege 
was funktioniert. 153l und 153ul funktionieren bei nicht.
Vlt. liegts auch ausnahmsweise am Compiler und nicht an mir :)

Das die uint64_t natürlich weit mehr speicher einnimmt ist das Unschöne 
an der Lösung.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kannst ja mal schauen, ob du dieses Stückchen Code im *.lss File 
findest. Daran liesse sich das evtl. verifizieren.

Ansonsten poste mal einen Testcase, d.h. ein absolut miminales Stück 
Code, das genau diesen Effekt produziert. Also ohne zig KB anderes Zeug 
drumherum was ausser dir sowieso niemand übersetzt kriegt.

Autor: Robin Tönniges (rotoe) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also in dem *.lss File steht viel. Und ich werde wohl voher an 
Altersschwäche sterben als das zu finden.

Mal gucken ob ich nen COde basteln kann der kurz und knackig diesen 
Fehler verursacht.

Autor: Robin Tönniges (rotoe) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uint32_t A;
uint16_t B = 9000;

//Hauptschleife
int main(void)
{    
  while(1)
  {
    A = (150 * B) / 100;
  //A ist laut µC 392
  }
  return(0);
}

So hier mal ein Code wo das selbe Problem besteht.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Robin Tönniges wrote:
>     A = (150 * B) / 100;
>   //A ist laut µC 392

Aus C-Sicht stimmt das auch.
Du mußt schreiben:

     A = (150UL * B) / 100;



Peter

Autor: Robin Tönniges (rotoe) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schön wärs :)
Funktioniert leider nicht. Komm ne ganz lange komische Zahl bei raus.

Autor: die ??? (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Robin Tönniges wrote:
> Komm ne ganz lange komische Zahl bei raus.

Nach wieviel Millionen while(1)-Durchläufen?

Autor: Robin Tönniges (rotoe) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was weiß ich hab nicht mitgezählt. LCD sagt lange Zahl. Und wenn ich was 
anderes nehme funktionierts ja also B nicht 9000 sonder 2 oder sowas.

Autor: die ??? (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Robin Tönniges wrote:
> hab nicht mitgezählt

;^)

Autor: Robin Tönniges (rotoe) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jaja. Das ist bei 16MHz nicht so einfach das kann ich dir sagen :)

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich glaube da hast du einen Volltreffer gelandet.
unsigned long A;
unsigned int B = 9000;

int main(void)
{    
    A = 150 * (long)B;
    return(0);
}
liefert bei -mmcu=attiny25 korrekterweise:
main:
        lds r22,B
        lds r23,(B)+1
        ldi r24,lo8(0)
        ldi r25,hi8(0)
        ldi r18,lo8(150)
        ldi r19,hi8(150)
        ldi r20,hlo8(150)
        ldi r21,hhi8(150)
        rcall __mulsi3
aber bei -mmcu=atmega16 fehlt ein bischen was:
main:
        lds r22,B
        lds r23,(B)+1
        ldi r24,lo8(0)
        ldi r25,hi8(0)
        call __mulsi3

Damit hängt m.E. das Ergebnis davon ab, was vorher in R18..R21 
drinsteht.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35872

Sieht so aus, also ob man diese Version auf AVRs mit Hardware-Multiplier 
besser nicht verwendet.

Autor: Robin Tönniges (rotoe) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab nen Bug gefunden? :)
Darf ich jetzt stolz auf mich sein^^

Das mit dem mega16 kommt hin. Ich verwende einen mega32.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Robin Tönniges wrote:

> Ich hab nen Bug gefunden? :)
> Darf ich jetzt stolz auf mich sein^^

Du darfst ihn behalten. ;-)

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:

> Schreibt bitte bugreports für sowas, mit nachvollziehbaren
> Codeschnipseln.

Einen davon hattest du höchstselbst als #30908 bereits vor über einem 
Jahr gemeldet ;-).

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Kaiser wrote:

> Einen davon hattest du höchstselbst als #30908 bereits vor über einem
> Jahr gemeldet ;-).

Ja, war auch aus einer Diskussion hier hervor gegangen -- und hat ja
zumindest zu Diskussionen unter den Entwicklern geführt.

Autor: TintiFax (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein großes "Hallo" an die C-Spezialisten und diesem Forum !

OK.
Mein Beitrag zu diesem Thema hier fällt nur bescheiden aus.
Der Grund ist hier wohl in meinen mangelnden C-Kenntnissen zu suchen.

Warum ich eigentlich was schreiben möchte liegt einzig allein in der
Tatsache, dass ich ausser in Assembler auch anfangen möchte in C- zu
proggen. (Basic fällt leider flach-mag die Sprache nicht so)

Ihr macht's mir also überhaupt nicht einfacher einen Compiler fuer meine
Projekte zu verwenden wenn man(n) das so liest.
Verstehe hier nur mal Bahnhof und "O-gott, O-gott" was wird das nur 
werden.

Ich hoffe ihr versteht meine Zweifel ein wenig !!??

Also just zu meiner Hauptfrage "Welche Compilerversion" sollte ein 
Anfänger denn verwenden ??
Um nicht gleich den Mut zu verlieren.

Verwende Hauptsächlich Atmega8, ATiny Typen,

Danke schon mal an dieser Stelle !!

mfg TintiFax

Autor: Helmut Wendler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Also just zu meiner Hauptfrage "Welche Compilerversion" sollte ein
>Anfänger denn verwenden ??

Grundsätzlich die neuste, da du keine alten Projekte hast und es somit 
auch nicht zu Kompatibilitätsproblemen kommen kann.

Zwar bringt jede neue Version Bugs mit sich aber die Hoffnung ist doch 
da, dass wenigstens mal ein paar alte Bugs behoben wurden.

Ok, problematisch ist, dass die Programme immer mehr Speicher brauchen. 
Wenn das so weiter geht, passt ein Programm für einen ATmega16 halt 
nicht mehr in einen ATMega16 rein, weil der Compiler zu viel Müll 
erzeugt.

Mit vorzüglicher Hochachtung,
Helmut Wendler

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.