Walter schrieb:> das subtrahieren von 0 war früher nicht da und ich möchte es auch in> Zukunft nicht da haben, was kann ich tun?
Es wird aber gar nicht 0 subtrahiert, sondern das Carry-Bit. Wie hats
das denn früher gemacht? Wie würdest du denn eine 16bit-Operation
effizienter hinbekommen??
Dr. Sommer schrieb:> Es wird aber gar nicht 0 subtrahiert, sondern das Carry-Bit.
Warum? Und warum vom selben Registerpaar? sbiw ist doch bereits eine 16
bit operation, oder?
Walter schrieb:> das subtrahieren von 0 war früher nicht da und ich möchte es auch in> Zukunft nicht da haben, was kann ich tun?
Optimierung Abschalten. 8-Bit-Schleifenvariable verwenden.
Grund: Der GCC hat deine Schleife umgedreht, statt
>> for(i=0;i<WLC;i++)
macht er
>> for(i=WLC;i;--i)
warum? 'i' kann er schön im Register-Paar r24,r25 behalten, der
Schleifenrumpf interessiert sich nicht für den Wert von 'i', insofern
ist nur die richtige Anzahl an Schleifendurchläufen wichtig, den Rest
darf er ändern wie er lustig ist.
Und Startwert WLC setzen, Subtraktion und Vergleich auf 0 ist eben
"schicker" als
auf 0 Initialisieren, Addieren, 16-Bit-Vergleich mit WLC durchführen.
> is recht, aber kannst Du auch was zu meiner die Frage sagen?
Klar, hier nochmals Deine Frage:
> [..] was kann ich tun?
Für
> warte
-schleifen gibts fertige Funktionen wie delay_[um]s(), die kannst Du
ohne Sorgen direkt benutzen. Oder Du kannst in selber in Assembler
hinschreiben was Du genau haben willst.
HTH und nix für ungut
Ingo schrieb:> Was genau stört dich denn daran? Ich meine wenn man in C programmiert> kümmert man sich nur im äußersten Fall um Assembler.
nun, mich stört, dass das nur ein Beispiel war, wo es leicht zu erkennen
ist.
Es tritt aber nicht nur da auf und ich möchte halt nicht unnötig Platz
und Zeit verschwenden. Ich habe nach der Neuinstallatuion eben vorher
und nachher verglichen.
Ich würde ja nichts sagen, wenn der gcc es halt nicht besser kann, aber
er konnte das schon Mal
@ Walter (Gast)
>nun, mich stört, dass das nur ein Beispiel war, wo es leicht zu erkennen>ist.>Es tritt aber nicht nur da auf und ich möchte halt nicht unnötig Platz
Oh Gott, 2 Bytes!
>und Zeit verschwenden.
Einen Takt.
>Ich würde ja nichts sagen, wenn der gcc es halt nicht besser kann, aber>er konnte das schon Mal
Wahrscheinlich sind die falschen Compilerschalter gesetzt. Ausserdem ist
i ein INT, und der ist nunmal 16 Bit. Den kann der Compiler nur bedingt
kleiner machen. Mach es so, dann ist deine Schleife maximal schnell.
Falk Brunner schrieb:> Wenn hochoptimale Ergebnisse will/braucht, MUSS Assembler nutzen. Punkt.
aber wenn man ihm glauben kann, dann würde ich auch der Grund
interessieren warum es schon mal anders ging.
Das hat wohl nicht mit "Hochoptimierung" zu tun, sondern ist eventuell
wirklich ein Bug.
Ahab schrieb:> Und Startwert WLC setzen, Subtraktion und Vergleich auf 0 ist eben> "schicker" als auf 0 Initialisieren, Addieren, 16-Bit-Vergleich mit WLC> durchführen.
Das ist es aber nur dann wirklich, wenn er nach der Subtraktion nicht
noch eine unnötige zweite Subtraktion mit 0 einfügt. Die stellt nämlich
genau den Vergleich dar, den man sich durch das Umdrehen der
Zählrichtung eigentlich einsparen wollte.
Falk Brunner schrieb:>>Es tritt aber nicht nur da auf und ich möchte halt nicht unnötig Platz>> Oh Gott, 2 Bytes!>>>und Zeit verschwenden.>> Einen Takt.
Ich finde die Frage, warum der Compiler auf einmal schlechter optimiert
als eine frühere Version und warum er zusätzliche Instruktionen einfügt,
durchaus gerechtfertigt.
> Wahrscheinlich sind die falschen Compilerschalter gesetzt.
Wleche sollten das denn sein?
> Ausserdem ist i ein INT, und der ist nunmal 16 Bit.
Ja, und? Bei 16 Bit muss man zwingend beim Zählen in jedem
Schleifendurchlauf nochmal 0 vom Wert abziehen und bei 8 Bit nicht?
> Mach es so, dann ist deine Schleife maximal schnell.
WLC ist aber nicht 100, sondern offenbar 14743. Wie soll das in 8 Bit
passen?
Falk Brunner schrieb:> Wenn hochoptimale Ergebnisse will/braucht, MUSS Assembler nutzen. Punkt.
Das ist zwar richtig, aber trotzdem keine Begründung für eine schlechte
Optimierung.
@ Rolf Magnus (rmagnus)
>Ich finde die Frage, warum der Compiler auf einmal schlechter optimiert>als eine frühere Version und warum er zusätzliche Instruktionen einfügt,>durchaus gerechtfertigt.
Ja.
>> Wahrscheinlich sind die falschen Compilerschalter gesetzt.>Wleche sollten das denn sein?
Kenn ich mich im Detail auch nicht aus.
>> Ausserdem ist i ein INT, und der ist nunmal 16 Bit.>Ja, und? Bei 16 Bit muss man zwingend beim Zählen in jedem>Schleifendurchlauf nochmal 0 vom Wert abziehen und bei 8 Bit nicht?
Sicher, wenn kein Optimierung eingeschaltet ist, denn es ist eine 16 Bit
Subtraktion, welche auf einem 8 Bit Prozessor meistens zwei
Subtraktionen (einmal Low Byte und eimal high Byte + Carry) benötigt.
Mit aktiver Optimierung macht der avr gcc ein subiw draus, wodurch eine
16 Bit Subtraktion mit einem Befehl, wenn gleich auch 2 Takten erfolgen
kann.
>> Mach es so, dann ist deine Schleife maximal schnell.>WLC ist aber nicht 100, sondern offenbar 14743. Wie soll das in 8 Bit>passen?
Womit man so oder so eine 16 Bit Subtraktion braucht.
Walter schrieb:> Es tritt aber nicht nur da auf und ich möchte halt nicht unnötig Platz> und Zeit verschwenden.
Du kannst (und sollst!) nichts anderes machen als Deinen Code
(menschenlesbar!) hinschreiben und davon ausgehen dass der Compiler
einigermaßen gut optimiert. Einigermaßen bedeutet er tut alles was in
seiner Macht steht und das ist unterm Strich schon nicht schlecht. An
einigen Stellen wird er sogar Optimierungen finden an die hättest selbst
Du nicht gedacht, an anderen Stellen hättest Du vielleicht von Hand noch
2 Takte rausgekitzelt oder ein paar Bytes gespart aber unterm Strich ist
der gcc schon gar nicht mal so schlecht. Manchen sagen sogar er ist
eigentlich ganz gut und auf jeden Fall ist er mindestens doppelt so gut
wie die kastrierten 8 Bit Compiler von Microchip für PIC.
Das Wichtigste ist daß Du Deinen Code hinschreiben kannst ohne Dir
allzuviele Gedanken darüber zu machen und darauf zählen kannst daß beim
Compilieren kein haarsträubender Unsinn rauskommt. Wo Du die Grenze von
"haarsträubend" hinlegst ist natürlich eine persönliche Entscheidung,
aber ich würde sie nicht näher als vielleicht 20% vom theoretischen
Optimum entfernt hinlegen und das schafft der gcc allemal.
Bernd K. schrieb:> Wo Du die Grenze von> "haarsträubend" hinlegst ist natürlich eine persönliche Entscheidung,> aber ich würde sie nicht näher als vielleicht 20% vom theoretischen> Optimum entfernt hinlegen und das schafft der gcc allemal.
scheinbar nicht. Wenn er statt eine Anweisung 2 Anweisungen macht, dann
liegt er 100% daneben.
Es geht darum, das er es schon mal besser gemacht hat!
Peter II schrieb:> scheinbar nicht. Wenn er statt eine Anweisung 2 Anweisungen macht, dann> liegt er 100% daneben.
Ich dachte es geht um das gesamte Programm und das was unterm Strich
an verpasster Einsparung übrig bleibt (so hab ich den zitierten Teil
verstanden, darauf bezog ich mich).
Vorzeitige (Mikro-)Optimierungen sind die Wurzel allen Übels und
verschwendete Lebenszeit. Von zehntausend Zeilen in Deinem Programm
werden vielleicht nachher nur zwei Dutzend wirklich zeitkritisch sein
und 90% der CPU-Zeit verbrauchen. Das findest Du leicht mit geeigneten
Profiling-Techniken raus und dann kannst Du Dich auf diesen einen Teil
konzentrieren (falls es sich überhaupt als nötig erweist [meistens
nicht]).
Und in den 9976 übrigen Zeilen gibts bestenfalls noch leichte
Ersparnisse an Flashverbrauch rauszuholen mit nem besseren Compiler
(sofern sowas überhaupt existiert) aber wahrscheinlich nicht mehr als
20%, also sch*** drauf, nimms wie es ist, es ist schon verdammt gut so
wie es ist, sehr viel besser wirds nicht mehr werden und spar Dir die
Zeit über diesen belanglosen Nebenkriegsschauplatz nachzugrübeln, es
bringt nichts.
Wenns an dieser einen Stelle wirklich schon mal besser funktioniert hat
und man das nachvollziehbar nachstellen kann und Dich das so sehr wurmt
hilft vielleicht auch ein Bug-Report aber ich würde nicht versuchen die
Luft anzuhalten bis es gefixt ist.
Peter II schrieb:> scheinbar nicht. Wenn er statt eine Anweisung 2 Anweisungen macht, dann> liegt er 100% daneben.>> Es geht darum, das er es schon mal besser gemacht hat!
genau so ist es.
Wie gesagt, ich beschwere mich nicht wenn ein open source tool nicht das
macht was ich will, aber es ging schon Mal deutlich besser und ich würde
gern wissen warum.
Vielleicht mache ich ja auch einen Fehler, aber den Schalter -Os habe
ich gesetzt wie immer und überhaupt ist der makefile auch der gleiche
wie vorher.
Bernd K. schrieb:> Vorzeitige (Mikro-)Optimierungen sind die Wurzel allen Übels und> verschwendete Lebenszeit.
Hier ist offenbar nur jemandem die selbst gebaute Delay-Loop um die
Ohren geflogen. Das frustet natürlich, liegt aber am falschen Ansatz,
weniger am Compiler.
Kann durchaus sein, dass in einer bestimmten Version des Compilers ein
anderes suboptimales Ergebnis rauskommt. Und das später dann vielleicht
wieder korrigiert ist. Das ist nicht schön, kann aber passieren.
A. K. schrieb:> Hier ist offenbar nur jemandem die selbst gebaute Delay-Loop um die> Ohren geflogen. Das frustet natürlich, liegt aber am falschen Ansatz,> weniger am Compiler.
es geht doch nicht im das delay. Man kann eine LED blinken lassen und
das gleiche Problem entsteht.
Es geht darum, das der Compiler (scheinbar) schlechter geworden ist.
Kann es jemand anders mit einem neuer als den 4.6.2 mal nachstellen?`
Peter II schrieb:> Es geht darum, das der Compiler (scheinbar) schlechter geworden ist.> Kann es jemand anders mit einem neuer als den 4.6.2 mal nachstellen?`
4.7.2 ist auch ok. 4.8.irgendwas gibts in debian-sid, müsste man mal
probieren.
> es geht doch nicht im das delay. Man kann eine LED blinken lassen und> das gleiche Problem entsteht.
Jo, aber der Code ist ja nicht falsch, nur suboptimal. Was bei einer
Delay-Loop fatal sein kann.
Peter II schrieb:> Es geht darum, das der Compiler (scheinbar) schlechter geworden ist.
Die aktuelle ofizielle gcc Toolchain von Atmel fixt aber auch einige
Bugs die vorher drin waren. Zum Beispiel hat eine ältere Version (ich
glaub es war die bei Ubuntu (12 oder 14) mitgelieferte) einfach mal
globale Registervariablen wegoptimiert. Komplett wegoptimiert samt allen
Codes der sie verwendet hat! Einfach weg!
Die aktuelle Atmel-Toolchain von deren Webseite macht das nicht mehr.
Deshalb verwende ich jetzt nur noch die. Solche Showstopper (oder besser
deren Abwesenheit) wären mir wichtiger als irgendeine winzige vergessene
Optimierung.
Dispol schrieb:> Ich habs das gleiche "Problem" mit 4.8.2Peter II schrieb:> kann es auch im>> avr-gcc (AVR_8_bit_GNU_Toolchain_3.4.5_1522) 4.8.1>
Danke, dann muss ich wohl damit leben.
Schade dass 1,05 Schritte vorwärts, einer zurück wohl ein Naturgesetz
ist ;-)
Walter schrieb:> das subtrahieren von 0 war früher nicht da und ich möchte es auch in> Zukunft nicht da haben, was kann ich tun?>> gcc version 4.8.2 (GCC)
Vermutlich PR60486, behoben in 4.8.3+, evtl. auch PR61055, behoben in
4.8.3+ und 4.9.1+:
http://gcc.gnu.org/PR60486http://gcc.gnu.org/PR61055