[gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?

Na, indem Du nicht struct x in struct y einfügst. Wenn Du das machst solltest Du ja dafür einen bestimmten Grund gehabt haben oder es war schlicht unüberlegt, wenn Du das überhaupt nicht wolltest.

Das kannst im Endeffekt nur Du wissen.

Gruß Tommy

Hatten wir doch schon in #pragma pack(1) mit seinen Nachteilen ...

Ein ESP32 mag nun mal 32 bit Grenzen lieber, und braucht auch sonst schonmal mehr RAM als ein 8bit Controller. (Schonmal sizeof(char*) ausprobiert?)

Was aber, wenn ich zwei verschidene Instanzen des Types x in dem Typ y haben will? Muss ich dann alles als Array benutzen oder die Variablen kopieren und ein wenig umbenennen? Ich dachte eigentlich, dass structs dafür da sind, dass man einerseits alle Variablen in einem Objekt zusammenfassen kann und andererseits ein struct als Parameter für eine Funktion mitgeben kann. Zum Beispiel arbeite ich momentan mit einem Musikprogramm mit Oszillatoren, bei denen immer zwei Oszillatoren mit einem struct zusammengefasst werden (struct RingOsc{Osc osc1, osc2; ...};), damit man diese zwei Oszillatoren untereinander verstimmen und Ringmodulieren kann. Ich bin ja ein großer Fan vom SID-Chip und das sollte sowas wie ein SID 2.0 werden. Müsste ich jetzt osc1 und osc2 durch die ganzen Variablen, aus denen Osc besteht, ersetzen?

Argh!
Ich habe mir doch glatt die Antwort selber gegeben: Man kann es als Parameter mitgeben, also muss es ein zusammenhängender Haufen sein! :confused::blush:

Oder mehrere Haufen in mehreren Parametern.

Gruß Tommy

Sei lieber froh, dass gelegentlich ein bool weniger als 32 bit braucht auf deinem ESP32 :slight_smile:

michael_x:
Sei lieber froh, dass gelegentlich ein bool weniger als 32 bit braucht auf deinem ESP32 :slight_smile:

Ich bin nicht in der Lage, meine extreme Begeisterung in Worte zu fassen.

@michael_x: Naja, man könnte ja 32 boolsche Werte in 32 Bit speichern :wink:
Das hast Du aber sicher nicht gemeint.

Gruß Tommy

Nach dem ich mir das durchgelesen habe ....

Du solltest dich mit dem Padding arrangieren.
Und nicht auf Byte komm raus optimieren.

Die Verwendung von uint8_t und seinen Brüdern ist auf 16, 32 und 64 Bit Maschinen sehr dicht an Unsinn, da meist mit erheblicher Rechenlast verbunden.

int , ist das natürliche Maß der Dinge (außer auf den 8 Bit Dingern)

Tipp:
Für ungenutzten Speicher, gibts kein Geld zurück.

Tommy56:
@michael_x: Naja, man könnte ja 32 boolsche Werte in 32 Bit speichern :wink:

Naja, das machen ja z.B. OLED-Libs und das sind ja die Sachen, die wirklich viel Speicher ziehen. Bei meinem vor Jahren programmierten Semi-Textadventure war es mir egal, ob "bool taschenlampeAn" und "bool wandEntdeckt" jeweils eigene Bytes verbrauchen.

combie:
Nach dem ich mir das durchgelesen habe ....

Du solltest dich mit dem Padding arrangieren.
Und nicht auf Byte komm raus optimieren.

Die Verwendung von uint8_t und seinen Brüdern ist auf 16, 32 und 64 Bit Maschinen sehr dicht an Unsinn, da meist mit erheblicher Rechenlast verbunden.

int , ist das natürliche Maß der Dinge (außer auf den 8 Bit Dingern)

Tipp:
Für ungenutzten Speicher, gibts kein Geld zurück.

Jaja, ich weiß. Alles ist eine Sache der richtigen Balance zwischen Cycle- und RAM-Verbrauch. Ich will jetzt nicht unbedingt 5 FPS gegen 50 Bytes tauschen. Es ging mir eher ums Prinzip. Solange ich ein Byte ohne Nachteile streichen kann, tue ich's natürlich. Und uint8_t und co ist auf einem ESP Stuss? Das zieht wirklich mehr Cycles pro Operationals uint32_t? Puh, hat sich die Welt seit dem 6502 weiterentwickelt. Ich weiß nicht, was ich davon halten soll. Und ich habe die ganze Zeit bei jeder Variable nachgedacht, ob nicht doch weniger Bytes reichen, denn das wird ja nur den positiven Effekt von gespartem RAM haben. Soviel dazu. Gilt das auch für uint8_t[]?

combie:
Tipp:
Für ungenutzten Speicher, gibts kein Geld zurück.

Der Tipp ist sehr gut.

Gruß Tommy

Ach ja: Ist uint32_t besser als int32_t, wenn es um Geschwindigkeit geht?

Puh, hat sich die Welt seit dem 6502 weiterentwickelt. Ich weiß nicht, was ich davon halten soll.

  • Natürlich geht die Entwicklung weiter
  • Und ebenso natürlich ist es beim 6502 nichts anders, als beim ESP

Merke:
Der natürliche Datentype lässt sich am schnellsten verarbeiten.
Exotische/künstliche Datentypen, müssen maskiert, geschoben und/oder sonstwie umgerechnet werden.

Beim 6502 sind die natürlichen Typen (8Bit) die schnellsten
Beim AVR sind die natürlichen Typen (8Bit) die schnellsten
Beim ESP sind die natürlichen Typen (32Bit) die schnellsten
Beim K210 sind die natürlichen Typen (64Bit) die schnellsten

Also:
Wenn du also meinst, da hätte sich was dran geändert, dann steckt da ein Irrtum.
Denn selbst zu 6502 Zeiten war das nicht anders, dir sind nur damals die 16, 26, 32, 36 Bit Rechner nicht begegnet.
Aber "nicht begegnet" heißt nicht: "Gab es nicht"

Ach ja: Ist uint32_t besser als int32_t, wenn es um Geschwindigkeit geht?

Auch das ist Prozessorspezifisch.
Einzig bei int kann man sich sicher sein.
Nur nicht, ob int signed oder unsigned ist (Prozessorspezifisch).

Nachtrag:

Du solltest dir evtl die Definition von Byte mal durchlesen.
Das kann ein echter Augenöffner sein.

combie:
Tipp:
Für ungenutzten Speicher, gibts kein Geld zurück.

Wie man's sieht ... wenn man ein PC-Spiel verkaufen will, dann dürfte sich das besser verkaufen, wenn auch schon beim typischen 8GB-RAM-PC gut läuft.

combie:
Wenn du also meinst, da hätte sich was dran geändert, dann ist dein Kopf falsch verdrahtet.
Denn selbst zu 6502 Zeiten war das nicht anders, dir sind nur damals die 16, 26, 32, 36 Bit Rechner nicht begegnet.
Aber "nicht begegnet" heißt nicht: "Gab es nicht"

Ich meinte das nicht ganz von der Zeit her, sondern von der Entwicklung. Das NES wurde auch noch benutzt, als schon der Mega-Drive draußen war, genauso wie der C64 noch in Amiga-Zeiten. Ich meinte das eher von der Entwicklung her betrachtet. Natürlich werden riesige Rechenzentren nicht mit aus "Speak & Spell"s gestohlenen 4-Bit-Chips betrieben. Die werden da auch schon in der 8-Bit-Zeit mindestens 32 Bit gehabt haben. Ich meinte das eher als Beispiel für einen typischen 8-Bit-Prozessor. Ich dachte erst recht seit dem 6502-Assembler-Crashkurs vor einer Woche oder so, dass Addieren mit 8 Bit immer das Simpelste ist, da das nur ein Befehl ist, bei 16 Bit aber kompliziert wird. Außerdem habe ich mal irgendwo gehört, dass bei Maschinen mit mehr als 8 Bit die Register in obere und untere Hälfte eingeteilt sind, welche wiederrum beide in obere und untere Hälfte eingeteilt sind, bis man irgendwann bei Bytes ist. Daher dachte ich, dass 8 Bit vielleicht nicht schneller, aber auf jeden Fall nicht langsamer als int ist.

Nehmen wir mal einen 32-Bit-Rechner.
Der liest in einem Zug auch die 32 Bit (sein Datenwort) in sein 32 Bit Register ein. Das ist von der Größe auch sein int.
Wenn er damit arbeiten kann ist er fertig und kann weiter machen.

Wenn er davon nur 1 Byte betrachten soll, kommt es jetzt darauf an, welches Byte es ist.

Das Niederwertige: Mit 0xff maskieren ok
Das 2. von unten: um 8 Bit nach rechts schieben, mit 0xff maskieren ok
Das 3. von unten: um 16 Bit nach rechts schieben, mit 0xff maskieren ok
Das obere : um 24 Bit nach rechts schieben, mit 0xff maskieren ok

Das alles kostet Prozessorzeit.

Das war jetzt etwas vereinfacht, zeigt aber das Grundprinzip.

Gruß Tommy

Außerdem habe ich mal irgendwo gehört, dass bei Maschinen mit mehr als 8 Bit die Register in obere und untere Hälfte eingeteilt sind, welche wiederrum beide in obere und untere Hälfte eingeteilt sind, bis man irgendwann bei Bytes ist.

Einzelfälle, ja.

Aber ein universelles Prinzip?
Nein, ganz und gar nicht.
Eher eine Ausnahme.

HTML-Fan:
Ich dachte erst recht seit dem 6502-Assembler-Crashkurs vor einer Woche oder so, dass Addieren mit 8 Bit immer das Simpelste ist, da das nur ein Befehl ist, bei 16 Bit aber kompliziert wird.

Es gibt auch 8 Bit Prozessoren bei denen ein paar Register zu 16 Bit Registern kombinierbar sind. z.B. Z80 oder 8080/8085. Dadurch sind direkte 16 Bit Operationen in begrenzten Umständen möglich

Tommy56:
Nehmen wir mal einen 32-Bit-Rechner.
Der liest in einem Zug auch die 32 Bit (sein Datenwort) in sein 32 Bit Register ein. Das ist von der Größe auch sein int.
Wenn er damit arbeiten kann ist er fertig und kann weiter machen.

Wenn er davon nur 1 Byte betrachten soll, kommt es jetzt darauf an, welches Byte es ist.

Das Niederwertige: Mit 0xff maskieren ok
Das 2. von unten: um 8 Bit nach rechts schieben, mit 0xff maskieren ok
Das 3. von unten: um 16 Bit nach rechts schieben, mit 0xff maskieren ok
Das obere : um 24 Bit nach rechts schieben, mit 0xff maskieren ok

Das alles kostet Prozessorzeit.

Das war jetzt etwas vereinfacht, zeigt aber das Grundprinzip.

Gruß Tommy

Allerdings glaube ich zu wissen, dass bei einem 6502 die Operation Byte + Byte 8 Cycles kostet, ich vermute, das liegt daran, dass für jedes Bit der Übertrag geprüft wird. Wenn bei einer 32-Bit-Maschine 4-Byte + 4-Byte 32 Cycles kostet, dann könnte man sich ja einen anderen schlauen Assembler-Befehl für 8-Bit-Addition mit 8 Cycles ausdenken. Was ist an dieser Schlussfolgerung falsch?