Hallo,
ich habe ein Programm das u.a. momentan:
1) uint16 Arrays im PROGMEM hat
2) diese ausließt und verodert und dann in einen Array schreibt
3) Eine Funktion ließt diese uint16 werte, splittet sie und schreibt die
beiden uint8_t auf SPI
Ich frag mich nun ob es schlauer ist das alles mit uint8_t zu machen,
oder ob der Compiler das weg optimiert.
Meinem Programmierstiel? Nun ja ich programmiere normaler weise nicht c
;)
uint16t bot sich halt an, da dies der Ausgabe am nächsten ist, warum
genau ist das jetzt schlechter Programmierstil?
Davon abgesehen: Ich vergaß zu erwähnen, dass ich für den Atmega168
programmiere. Deshalb auch die Frage, denn dieser hat ja größten Teils 8
Bit Register.
qqeettuu schrieb:> Deshalb auch die Frage, denn dieser hat ja größten Teils 8> Bit Register.
Deshalb die Antwort: schlechter Stil.
Jede Operation auf einer 16-bit Variablen wird vom Compiler in mehrere
Operationen übersetzt, d.h. der Einsatz von 16-bit Variablen
(1) benötigt mehr Taktschläge
(2) benötigt mehr Speicher.
Daher meiden, wenn nicht ungedingt nötig. Oder auf ne 32-bit Arch
aufsteigen.
qqeettuu schrieb:> Hallo,> ich habe ein Programm das u.a. momentan:> 1) uint16 Arrays im PROGMEM hat> 2) diese ausließt und verodert und dann in einen Array schreibt> 3) Eine Funktion ließt diese uint16 werte, splittet sie und schreibt die> beiden uint8_t auf SPI>> Ich frag mich nun ob es schlauer ist
Kann man so nicht sagen.
Sind das konzeptionell von vorne herein 16-Bit Werte oder sind es eher
8-Bit Werte, die aus irgendwelchen unerfindlichen Gründen zu 16 Bit
zusammengefasst wurden?
Am besten fährt man, wenn man erst mal die Dinge so macht, wie sie am
logischten sind. Also die Datentypen, die sich konzeptionell anbieten.
Dann sieht man nach, ob es Optimierungsbedarf gibt.
Und erst dann, wenn Optimierungsbedarf besteht, fängt man an zu
tricksen.
Prinzipiell kann man bei einer 8-Bit-Architektur (davon reden wir doch?)
sagen dass alles grösser als int8 eben zusammengesetzt werden muss. Man
sollte seine Datentypen also immer so wählen, dass möglichst nichts
vergeudet wird.
Bei Arrays im Datenspeicher ist es sinnvoller Dir ein gepacktes Bitfeld
(struct) zu bauen, welches Du in einem Array verwaltest. Dadruch kannst
Du ggf. recht viel Speicher sparen, es geht aber auch zu Lasten des
Programmspeichers -- versteht sich.
Greets,
Michael
qqeettuu schrieb:> Ich frag mich nun ob es schlauer ist das alles mit uint8_t zu machen,
Was meinst du damit? Benötigst du in Wirklichkeit nur 8 bit Werte?
Weshalb hantierst du mit 16 bit Datentypen, wenn auch 8 bit Typen
ausreichen würden?
Ich hab mich wohl missverständlich ausgedrückt:
logisch gesehen habe ich 16bit werte (die darstellen, welche LEDs an
oder aus sind)
Daher kam die Idee diese als uint16_t zu speichern. Nun muss ich diese
aber im Endeffekt als uint8_t über SPI übertragen. (Voher werden sie
noch teilweise verodert)
Auf der einen Seite ist natürlich schön, dass 16 bit Werte genau das
darstellen was ich auch nachher sehe, aber auf der andern Seite frage
ich mich ob das nicht zu viel Overhead erzeugt.
Ach die gedanken sind momentan für einen Atmega168
qqeettuu schrieb:> Auf der einen Seite ist natürlich schön, dass 16 bit Werte genau das> darstellen was ich auch nachher sehe, aber auf der andern Seite frage> ich mich ob das nicht zu viel Overhead erzeugt.
Dafür behandelst du aber immer 2 Byte auf einmal und du musst keine
Klimmzüge machen um den Zusammenhang der beiden Bytes zu gewährleisten.
Was ist Sache?
Ist dein Code zu langsam?
Wenn ja, dann mach dir Gedanken. Wenn nein, worüber reden wir dann
überhaupt?
qqeettuu schrieb:> logisch gesehen habe ich 16bit werte (die darstellen, welche LEDs an> oder aus sind)
Dein Problem: Du kannst nicht programmieren. Lass die armen LEDs in
Frieden.
Mehr ist dazu nicht zu sagen.
@ kbuchegg:
Vielleicht ist das wirklich übertriebene micro Optimierun and dieser
Stelle. Ich dachte halt nur, dass ich das gleich "richtig" machen
sollte, damit das auch vielleicht auf einem kleinerem Chip läuft. Aber
richtig liegt ja im Auge des Betrachters ;)
@puh:
Sry, aber was soll das jetzt? Wenn ich alles könnte würde ich nicht
fragen.
qqeettuu schrieb:> Wenn ich alles könnte würde ich nicht fragen.
Wenn du irgendetwas könntest, hättest du auch nicht gefragt.
Du quälst dich mit einem Kodierungsproblem herum.
Ich denke, Mikrocontroller, Compiler und ähnliches sind nichts für dich.
Vielen Dank an alle die konstruktive Beiträge geschrieben haben. Für
mich ist jetzt klar, dass ich Takte und Speicher verschwende und werde
dies ändern sobald ich Performance Problem merke.
klausr:
Es geht um 128 LEDS. Ein bit in einem uint16 repräsentiert eine LED.
puh:
ganz schön Angriffslustig, hmm? Du möchtest also sagen ich kann nichts.
Nunja du scheinst mich gut zu kennen. Ich werde deinem Ratschlag folgen
und alle elektronischen Geräte verbannen ;)
qqeettuu schrieb:> ganz schön Angriffslustig, hmm? Du möchtest also sagen ich kann nichts.
Nunja wir zerbrechen uns hier die kostbaren Köpfe, wobei sich hinterher
rausstellt, dass es bei dir sowieso egal ist, ob 8 oder 16 bit. Dein
hässlicher LED-Cube blinkt trotzdem nur sehr langsam.
qqeettuu schrieb:> klausr:> Es geht um 128 LEDS. Ein bit in einem uint16 repräsentiert eine LED.
Aha.
Das heißt in Wirklichkeit haben wir es gar nicht mit 16 LED und einem
uint16_t zu tun, sondern mit 128 LED und einem nicht existenten
Datentyp.
Nun gut. Die Frage ist an dieser Stelle. Musst du ständig alle 128 LED
auf einmal bearbeiten oder machst du das in 16 BIt Happen oder in 8 Bit
Happen.
Wie machst du das und warum?
Denn wenn in Wirklichkeit von 128 LED die Rede ist, dann eine 16 Bit
Verarbeitung nicht mehr oder weniger naheliegend als eine 8 Bit.
puh:
ok, entschuldige, die überflüssige Denkanstrengung. Also schreibe ich
lieber einen irgendwie funktionierenden Code, der aber sonst total
grottig ist. Mein Problem war halt, dass ich den overhead nicht wirklich
einschätzen konnte und lieber nachfragen wollte wie man das richtig
macht.
Han sel schrieb:> Karl-Heinz, dir ist doch klar dass es hier um "Kodierung" geht, oder?> Natürlich ist das alles in 8-bit machbar. Das garantiere ich dir.
Es geht nicht darum was machbar ist.
Es geht darum, dass er was lernt, wie man solche Dinge entscheiden kann.
Und wie sich jetzt rausstellt, muss er erst mal mit Informationen
rüberrücken, was er da wirklich macht.
Von der ursprünglichen Aussage "16 Bit ist eine naheliegende
Organisationsform", ist nach seinem letzten Posting erst mal nichts
übrig geblieben. Wenn eigentlich von 128 LED die Rede ist, dann ist 16
Bit nicht mehr oder weniger naheliegend wie 8 Bit.
Karl Heinz Buchegger schrieb:> wie sich jetzt rausstellt, muss er erst mal mit Informationen> rüberrücken, was er da wirklich macht.
Mir reichen die Infos, um zu wissen, dass der Herr den Mikrocontroller
weglegen sollte, und sich stattdessen mit einem Buch befassen sollte.
Karl Heinz Buchegger schrieb:> Denn wenn in Wirklichkeit von 128 LED die Rede ist, dann eine 16 Bit> Verarbeitung nicht mehr oder weniger naheliegend als eine 8 Bit.
Das war mir schon sehr viel früher klar:
Han sel schrieb:> wobei sich hinterher> rausstellt, dass es bei dir sowieso egal ist, ob 8 oder 16 bit.
qqeettuu schrieb:> puh:> ok, entschuldige, die überflüssige Denkanstrengung. Also schreibe ich> lieber einen irgendwie funktionierenden Code, der aber sonst total> grottig ist. Mein Problem war halt, dass ich den overhead nicht wirklich> einschätzen konnte und lieber nachfragen wollte wie man das richtig> macht.
Was denkst du, wie es andere gelernt haben?
Sie haben beides implementiert, haben sich die UNterschiede angesehen,
sowohl im Source Code als auch in der erzeugten Code-Größe und haben
dann für sich eine Entscheidung getroffen.
Und wir haben auch gelernt, dass die Antwort auf deine Frage ein
solides: "Sowohl als auch" sein kann. Soll heißen: es kommt auf die
Details an.
Wenn es einen Satz einfacher Regeln gäbe, mit denen jeder optimalen Code
schreiben kann, dann bräuchte es keine Spezialisten, die ihr Fach
jahrelang lernen.
Ja das ist alles in 8 Bit machbar. Wie oben geschrieben war nur die
Frage ob es schlauer ist alles in 8 Bit zu machen und diese Frage ist ja
nun geklärt.
kbuchegg:
Ich habe es nicht zugeschriebenen, aber natürlich wird das gemultiplext.
(8*16=128).
qqeettuu schrieb:> kbuchegg:> Ich habe es nicht zugeschriebenen, aber natürlich wird das gemultiplext.> (8*16=128).
Wie wäre es, wenn du jetzt endlich mal ein bischen Code zeigen würdest?
Denn auf 'alles aus der Nase ziehen' hab ich ehrlich gesagt mitlerweile
auch keine Lust mehr.
@Han sel
Kennt ihr beide euch?
Han sel schrieb:> Karl Heinz Buchegger schrieb:>> Kennt ihr beide euch?>> Zum Glück noch nicht. Jetzt sag mir nicht, er sei mein Nachbar!
Ich hoffe nicht ;)
So ich will hier in diesem Thread keine Zeit mehr vergeuden.
Entschuldigt, dass das so unschön gelaufen ist.
Für mich ist dank dieses Thread aber klar geworden, dass ich auf dem
Atmega168 auf jeden Fall Takte und Speicher verschwende und werde mal
beobachten wie sich dieser Overhead weiter auswirkt.
Danke
Ein bisschen spaßig wars ja trotzdem.
Grundsätzlich lassen sich (meist eher jüngere) Leute gerne dazu
hinreißen, in den Weiten des Internets eine "Antwort" auf irgendeine
gerade aufkommende Frage zu suchen, anstatt sich selbst mit der Materie
zu beschäftigen. Es ist das böse Halbwissen, wobei eine Hälfte meist
schon übertrieben wäre. Das finde ich schade.
Han sel schrieb:> Karl Heinz Buchegger schrieb:>> Kennt ihr beide euch?>> Zum Glück noch nicht. Jetzt sag mir nicht, er sei mein Nachbar!
:-)
Kommt öfter vor, dass hier ein Schüler aufschlägt dessen Banknachbar
dann erst mal kein gutes Haar an ihm lässt (weil er ihn aus dem
Unterricht kennt). Und so wie du von Anfang an über ihn hergezogen bist
....
qqeettuu schrieb:> So ich will hier in diesem Thread keine Zeit mehr vergeuden.> Entschuldigt, dass das so unschön gelaufen ist.>> Für mich ist dank dieses Thread aber klar geworden, dass ich auf dem> Atmega168 auf jeden Fall Takte und Speicher verschwende und werde mal> beobachten wie sich dieser Overhead weiter auswirkt.
?
Also: Wie Einige schon festgestellt haben, macht hier ein uint16 nicht
unbedingt Sinn. Meine Empfehlung: Auf einem 8-bit System mit unit8
organisieren, auf einem 32-bit System mit 32-bit Ints. Grund: Zumindest
frühe ARM Systeme haben die meisten arithmetischen und logischen
Operationen immer 32 bit breit ausgeführt. Bei 8 und 16 bit wurde da
freudig hin und her gecastet.
Allerdings: Wenn dein Code läuft und du sonst keine Probleme hast, lass
es so wie es ist...
Der AVR verarbeitet auch 16 Bit Variabeln recht fix, trotz 8 Bit
Architektur. 32 und 64 war mal recht mies, das soll aber jetzt besser
sein. Da die Daten am Ende sowieso per 8 Bit und SPI raus müssen, würde
ich einfach ein Array aus uint8_t nutzen. Aber auch uin16_t ist OK, der
Unterschied wird nicht weltbewegend sein.
Han sel schrieb:> Grundsätzlich lassen sich (meist eher jüngere) Leute gerne dazu> hinreißen, in den Weiten des Internets eine "Antwort" auf irgendeine> gerade aufkommende Frage zu suchen, anstatt sich selbst mit der Materie> zu beschäftigen. Es ist das böse Halbwissen, wobei eine Hälfte meist> schon übertrieben wäre. Das finde ich schade.
Wobei du keinen Deut dazu beigetragen hast, dieses unterstellte
Halbwissen in Richtung Wissen zu ergänzen.
Wenn deine "edle Birne" zu schade ist, etwas zu erklären, dann sei
wenigstens nicht so kontraproduktiv, demotivierent oder gar destruktiv.
Wenn dir diese Art, nach einer Antwort zu suchen, nicht gefällt, dann
sei einfach still anstatt so verbitterte und kleingeistige Beiträge zu
schreiben. Das hilft keinem weiter und spricht auch nicht für dich.
Han sel schrieb:> Dein Problem: Du kannst nicht programmieren. Lass die armen LEDs in> Frieden.>> Mehr ist dazu nicht zu sagen.
Dann aber trotzdem immer nicht weiter:
Han sel schrieb:> Wenn du irgendetwas könntest, hättest du auch nicht gefragt.> Du quälst dich mit einem Kodierungsproblem herum.>> Ich denke, Mikrocontroller, Compiler und ähnliches sind nichts für dich.
etc.
Johann, du scheust die Wahrheit über selbstständiges Lernen genauso wie
qqeettuu ein gutes Buch. Ich gebe es auf, die Greenhörner
zurechtzustutzen. Schade um Karl-Heinz, den alten Sysophos. Möget ihr
samt euren LEDs den Seelenfrieden finden, den ich euch bisher streitig
gemacht habe.
Beim AVR-GCC gilt speziell, man nimmt den kleinsten ausreichenden Typ
von uint8_t, uint16_t oder uint32_t.
Darüber hinaus nimmt man ein Array aus uint8_t.
Muß man rechnen, kann man auch noch uint64_t nehmen, aber das ist
schlechter optimiert.
Peter
Han sel schrieb:> Johann, du scheust die Wahrheit über selbstständiges Lernen genauso wie> qqeettuu ein gutes Buch.
Und was hat die "Wahrheit" wie auchimmer sie aussehen mag — mit deinen
Attitüden wie Überheblichkeit und Arroganz zu tun?
Tom M. schrieb:> Was meinst du damit? Benötigst du in Wirklichkeit nur 8 bit Werte?> Weshalb hantierst du mit 16 bit Datentypen, wenn auch 8 bit Typen> ausreichen würden?
... weil er vielleicht annimmt, dass es sich bei 16 bit Werten um
Integer handelt und dieser C-Datentyp ist für jedes System definiert als
Datentyp, der direkt von der Hardware unterstützt wird, also somit am
schnellsten ausgeführt wird.
Konsequenterweise heißt das, dass eine 8-bit Maschine auch ein "int" mit
8-bit hat.
Checker-Bunny schrieb:> Tom M. schrieb:>>> Weshalb hantierst du mit 16 bit Datentypen, wenn auch 8 bit Typen>> ausreichen würden?>> ... weil er vielleicht annimmt, dass es sich bei 16 bit Werten um> Integer handelt und dieser C-Datentyp ist für jedes System definiert als> Datentyp, der direkt von der Hardware unterstützt wird, also somit am> schnellsten ausgeführt wird.
Nö, nicht notwendigerweise :-)
Warum soll auf einem 64-Bit System ein int 64 Bit groß sein müssen?
Oder umgekehrt. Es ist naheliegend, aber keineswegs zwingend. Ditto
für 16-Bit und 32-Bit Systeme.
> Konsequenterweise heißt das, dass eine 8-bit Maschine auch ein "int" mit> 8-bit hat.
Nicht, wenn es gültiges C ist, denn dor ist ein int immer mindestens 16
Bits weit.
avr-gcc kennt den Schalter -mint8, mit dem ein sizeof (int) = 1 ist.
Aber der erzeugte Code entspricht wie gesagt dem, was der C-Standard
vorschreibt
Johann L. schrieb:> avr-gcc kennt den Schalter -mint8, mit dem ein sizeof (int) = 1 ist.> Aber der erzeugte Code entspricht wie gesagt dem, was der C-Standard> vorschreibt
Hast Du dich da nicht verschrieben?
Der erzeugt Code ist nicht mehr C-konform, da sizeof(int) < 16.
Man muss also genau wissen was man tut, wenn man den Schalter aktiviert.
Johann L. schrieb:>> ... weil er vielleicht annimmt, dass es sich bei 16 bit Werten um>> Integer handelt und dieser C-Datentyp ist für jedes System definiert als>> Datentyp, der direkt von der Hardware unterstützt wird, also somit am>> schnellsten ausgeführt wird.>> Nö, nicht notwendigerweise :-)>> Warum soll auf einem 64-Bit System ein int 64 Bit groß sein müssen?> Oder umgekehrt. Es ist naheliegend, aber keineswegs zwingend. Ditto> für 16-Bit und 32-Bit Systeme.
ISO C empfielt es, bzw. erwähnt, daß es so gedacht ist, schreibt es aber
nicht vor. Bei 64-bit-Plattformen wird es meistens auch nicht gemacht,
weil einem sonst die Integer-Typen unterhalb davon ausgehen, denn man
will auch Typen für 8, 16 und 32 Bit haben, aber es gibt nur zwei
Standard-Integer-Typen, die kleiner sein dürfen als int.
>ich habe ein Programm das u.a. momentan:>1) uint16 Arrays im PROGMEM hat>2) diese ausließt und verodert und dann in einen Array schreibt>3) Eine Funktion ließt diese uint16 werte, splittet sie und schreibt die>beiden uint8_t auf SPI>>Ich frag mich nun ob es schlauer ist das alles mit uint8_t zu machen,>oder ob der Compiler das weg optimiert.
==> Zurück zum Start:
uint16 ist in diesem Fall eher die bessere Variante, da die Arrays ja im
Progmem liegen, der ist beim AVR in 16 Bit Worten organisiert! Die
Assembler-Befehle LPM und SPM lesen oder scheiben dementsprechend immer
gleich 16 Bit Werte in oder aus dem Z-Register (16Bit)
Peter schrieb:> Die Assembler-Befehle LPM und SPM lesen oder scheiben dementsprechend> immer gleich 16 Bit Werte in oder aus dem Z-Register (16Bit)
Das Z-Register gibt die Adresse an. Der gelesene Wert ist aber nur 8
Bit breit.
Klaus Falser schrieb:> Johann L. schrieb:>> avr-gcc kennt den Schalter -mint8, mit dem ein sizeof (int) = 1 ist.>> Aber der erzeugte Code entspricht wie gesagt dem, was der C-Standard>> vorschreibt>> Hast Du dich da nicht verschrieben?
Ja, hab ich. Hier ein
> nicht
zur freien Verfügung ;-)