Arduino Forum

International => Deutsch => Topic started by: HTML-Fan on May 19, 2020, 01:59 pm

Title: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 01:59 pm
Hallo!

Ich habe weniger ein Problem, eher eine Frage: Warum in diesem Programm
Code: [Select]
struct Data{
  int16_t x;
  int16_t y;
  uint8_t hp;
};
Data data;
void setup() {
  Serial.begin(115200);
  Serial.println(sizeof(Data));
  uint8_t* pointer = (uint8_t*)&data;
  for(byte i = 0;i < sizeof(Data);i++){
    if(!(pointer[i] >> 4)) Serial.print("0");
    Serial.print(pointer[i], HEX);
    Serial.print("\t");
  }
  Serial.println();
  data.x = 1000;
  data.y = 0x1234;
  data.hp = 100;
  for(byte i = 0;i < sizeof(Data);i++){
    if(!(pointer[i] >> 4)) Serial.print("0");
    Serial.print(pointer[i], HEX);
    Serial.print("\t");
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}

, welches ich auf der Suche nach einer Möglichkeit, die Byte-Werte aus einer Instanz auszulesen, gibt an, dass sizeof(Data) 6 ist, dabei hat Data eine Größe von nur 5 Bytes. Klar, ich könnte einfach überall -1 rechnen, aber mir geht es darum, dass ich wissen will, warum das passiert. Außerdem würde das bedeuten, dass ich bei Arrays aus tausenden kleinen structs tausende Bytes verliere. Ich habe auch mal alle struct-Variablen gelöscht, wodurch die Größe ja 0 sein müsste, und sizeof(Data) ergab 1. Und ich habe es auch mit sizeof(data) probiert, da kam überall das Gleiche (Selbe?) raus. Weiß jemand von euch darüber mehr als ich?

Gruß
HTML-Fan
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 02:04 pm
Auf welchem MC? Auf dem UNO sagt er 5.

Gruß Tommy
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: uxomm on May 19, 2020, 02:09 pm
Also wenn ich dieses Programm auf einen Arduino UNO lade dann bekomme ich folgende Ausgabe:
Code: [Select]
5
00 00 00 00 00
E8 03 34 12 64

Also sizeof(Data) ist 5.

Arduino IDE 1.8.12 (portable), Windows 10
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 02:11 pm
Echt? Ich nutze den ESP32.
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: (deleted) on May 19, 2020, 02:13 pm
(deleted)
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: (deleted) on May 19, 2020, 02:14 pm
(deleted)
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 02:18 pm
Die 6 kommt beim ESP8266 (Alignment auf 32 Bit Prozessoren)

Gruß Tommy

Edit:
Das gibt dort sogar 12 (auf UNO/MEGA 7):
Code: [Select]

struct Data{
  uint8_t hp;
  int32_t y;
  int16_t x;
};
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Serenifly on May 19, 2020, 02:25 pm
Man kann hier nicht direkt 8 und 32 Bit Prozessoren vergleichen. Das hängt nämlich gerade mit der Speicherbreite/Wortgröße zusammen.

https://de.wikipedia.org/wiki/Speicherausrichtung (https://de.wikipedia.org/wiki/Speicherausrichtung)

Eventuelle Lösung:
https://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Structure_002dPacking-Pragmas.html (https://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Structure_002dPacking-Pragmas.html)
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 02:34 pm
Deshalb ergibt der Vergleich ja auch notwendigerweise ohne pack unterschiedliche Größen.

Gruß Tommy
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 02:52 pm
Eventuelle Lösung:
https://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Structure_002dPacking-Pragmas.html (https://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Structure_002dPacking-Pragmas.html)
Prima,
Code: [Select]
#pragma pack(1)
löst das "Problem". Hat das irgendwelche Nachteile, macht das z.B. 2-Byte-Operationen einen Strich durch die Berechnung?
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Serenifly on May 19, 2020, 03:03 pm
Der Speicherzugriff wird eventuell langsamer wenn die Datenstruktur über Speichergrenzen verteilt ist. Das hängt aber von der Prozessorarchitektur ab
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 03:07 pm
Das hängt aber von der Prozessorarchitektur ab
Wie ist das denn beim ESP32?
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 03:08 pm
Nach meiner Meinung sollte man pack nur dann verwenden, wenn man Strukturen zwischen verschiedenen Architekturen austauschen will (z.B. ESP8266 <--> NANO). Sonst sollte man den Kompiler seine Optimierungsarbeit machen lassen.

Gruß Tommy
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 03:09 pm

Nach meiner Meinung sollte man pack nur dann verwenden, wenn man Strukturen zwischen verschiedenen Architekturen austauschen will (z.B. ESP8266 <--> NANO).
War nicht der Plan, ich wollte eher sowas wie Speicherplätze realisieren, die ein RAM-Abbild darstellen.
Sonst sollte man den Kompiler seine Optimierungsarbeit machen lassen.
Gibt es die Möglichkeit, dass man nur bei bestimmten "struct"s Cycles gegen RAM tauscht?
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 03:13 pm
Das pack kannst/solltest Du auf jedes struct einzeln anwenden.

Gruß Tommy
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 03:14 pm
Dann so?
Code: [Select]
#pragma Data(1)
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 03:15 pm
Nee, das gibt wieder 6 Bytes.
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Serenifly on May 19, 2020, 03:17 pm
pack(n) kann man ja mehrmals verwenden oder auch mit pack() wieder die ursprüngliche Ausrichtung herstellen
Title: Re: Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 03:18 pm
Aha. Vielen Dank für die Infos, ich denke, dass ich erstmal bei schnellerem Zugriff bleibe, die FPS bei meinem Spiel fallen so schon gerne auf 25.
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: agmue on May 19, 2020, 03:25 pm
Wie ist das denn beim ESP32?
6
00   00   00   00   00   00   
E8   03   34   12   64   00   


Mit #pragma pack(1):

5
00   00   00   00   00   
E8   03   34   12   64   

Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 03:49 pm
6
00   00   00   00   00   00   
E8   03   34   12   64   00   


Mit #pragma pack(1):

5
00   00   00   00   00   
E8   03   34   12   64   


Ja, das weiß ich. Ich meinte, wie sieht das denn mit Speicherzugriffgeschwindigkeit bei einem ESP32 aus, da Serenifly
Das hängt aber von der Prozessorarchitektur ab
geschrieben hat.
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 03:51 pm
Ach ja, fast vergessen: Kann man das sizeof() dazu bewegen, nur die Anzahl der genutzen Bytes auszuspucken? Wenn ich einen Speicherstand habe, dann kann ich mir ja das Extra-Byte sparen.
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 03:59 pm
sizeof sagt Dir die tatsächliche Größe. Das zusätzliche Byte kann durchaus zwischendrin sein, d.h. Du musst es mit speichern, wenn Du die Struktur speichern und wieder einlesen willst. Du kannst durch die Anordnung der Teile des struct evtl. schon etwas optimieren. Schau Dir mal diesen Thread (https://www.arduinoforum.de/arduino-Thread-struct-wird-auf-einem-ESP8266-anders-behandelt-wie-auf-einem-Arduino) an.

Gruß Tommy
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 04:02 pm
Aha. Mist. Aber viel macht's dann ja eh nicht aus.
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 04:09 pm
Aber viel macht's dann ja eh nicht aus.
Schau Dir mal #6 an: von 7 auf 12 Bytes, wenn man es ungünstig anstellt.

Gruß Tommy
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 04:19 pm
Tatsächlich. Aber mit
Code: [Select]

struct Data{
  int32_t y;
  uint8_t hp;
  int16_t x;
};

sind's nur 8 Byte, das ist wieder nur ein Extra-Byte. Wie war das nochmal mit Kompiler und Optimierung?
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 04:22 pm
Wer lesen kann/will und die verlinkten Artikel versteht, versteht auch das.

Gruß Tommy
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 04:27 pm
Gibt es eine Regel, nach der man in structs Variablen verteilen sollte? Gibt es online Tools, die einem structs optimieren?
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 04:31 pm
Ja, die Ausrichtung verstehen. Den Rest macht brain 1.0.

Gruß Tommy
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 04:35 pm
Aha, ich glaube, ich hab's in etwa. Möglichst gleiche Typen hintereinander? Naja, ich habe ein paar lange structs und nicht exakt totale Lust, die Stück für Stück zu überarbeiten.
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 04:43 pm
Du hast es nicht verstanden. Damit kannst Du zwar zufällig etwas erreichen aber nicht gezielt.

Gruß Tommy

Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 05:06 pm
Funktioniert das in etwa so:
Die RAM-Variante von
Code: [Select]
struct xyz{
  uint8_t a;
  uint16_t b;
  uint16_t c;
  uint32_t d;
};

ist
Code: [Select]

0: a
1: -
2: Lb
3: Hb
4: Lc
5: Hc
6: -
7: -
8: Ld
9: d
A: d
B: Hd
...

Also würde es Sinn machen, wenn man xyz in
Code: [Select]
struct xyz{
  uint32_t d;
  uint16_t b;
  uint16_t c;
  uint8_t a;
};

umformt, also nach Größe geordnet, damit die RAM-Variante
Code: [Select]

0: Ld
1: d
2: d
3: Hd
4: Lb
5: Hb
6: Lc
7: Hc
8: a
...

ist. Oder?
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 05:18 pm
Ja. Die 32-Bit-Variablen an durch 4 teilbaren Anfängen anlegen und die 16-Bitt möglichst an durch 2 teilbaren.

Gruß Tommy
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 05:19 pm
Also doch nach Typen ordnen.
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 05:32 pm
Nach Längen in Bytes.

Gruß Tommy
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 05:34 pm
Und gibt es dafür Programme?
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 05:35 pm
Ja, brain Version 1.0 aber Vorsicht - oft gibt es nur die Betaversion 0.9 oder niedriger.

Gruß Tommy
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 05:43 pm
Mir fällt gerade noch was ein - nach Größen ordnen reicht noch nicht. Wenn man
Code: [Select]
struct x{
  uint32_t a;
  uint16_t b;
};
struct y{
  x d;
  uint32_t c;
  uint16_t e;
};

, also alles nach Größe geordnet hat, dann ergibt das (ich lasse jetzt mal H und L weg)
Code: [Select]

0: a
1: a
2: a
3: a
4: b
5: b
6: -
7: -
8: c
9: c
A: c
B: c
C: e
D: e

, bei
Code: [Select]
struct x{
  uint32_t a;
  uint16_t b;
};
struct y{
  uint32_t c;
  x d;
  uint16_t e;
};

aber
Code: [Select]

0: c
1: c
2: c
3: c
4: a
5: a
6: a
7: a
8: b
9: b
A: e
B: e

, oder?
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 05:50 pm
Schau Dir nochmal #32 an. Dein y ist nicht nach der Größe sortiert.

Es ist ja im Endeffekt:

Code: [Select]

  uint32_t a;
  uint16_t b;
  uint32_t c;
  uint16_t e;


Gruß Tommy
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Serenifly on May 19, 2020, 05:52 pm
Es geht nicht darum dass nach der Größe zu sortieren sondern die Speichergrenzen zu berücksichtigen. Die Größe ist egal solange man 4 Byte große Blöcke hat
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 05:57 pm
Ja und bei der angegebenen Reihenfolge hat man die für c halt nicht. Da wäre dann die andere Reihenfolge besser:

Code: [Select]

struct x{
  uint32_t a;
  uint16_t b;
};
struct y{
  x d;
  uint16_t e;
  uint32_t c;
};


Gruß Tommy
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 06:07 pm
Hier wird's dann aber beknackt:
Code: [Select]
struct x{
  uint32_t a;
  uint16_t b;
  uint8_t c;
};
struct y{
  uint32_t d;
  x e;
  uint16_t f;
};

ergibt bei y
Code: [Select]

0: d
1: d
2: d
3: d
4: e.a
5: e.a
6: e.a
7: e.a
8: e.b
9: e.b
A: e.c
B: -
C: f
D: f

Bei struct y hat man dann

Code: [Select]

struct y{
  uint32_t d;

 [uint32_t e.a;
  uint16_t e.b;
  uint8_t e.c;]

  uint16_t f;
};

und da ist es unmöglich, alles richtig zu ordnen, da man ja nicht den struct so leicht zerpflücken und eine Variable dazwischenschieben kann. Gibt es echt nicht irgendeine Möglichkeit, mit der der Kompiler das zerlegt und ordnet? Da hilft nämlich nichtmal Brain 1.1 weiter.
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 06:14 pm
Ich habe ja nicht behauptet, dass es immer möglich wäre ohne Ausrichtungs(füll)bytes auszukommen.
Man kann aber versuchen, Anordnungen zu wählen, die davon wenige brauchen. Um mehr geht es nicht.

Wie sollte der Kompiler etwas zerlegen und anders anordnen, was Du ihm anders vorgibst?

Gruß Tommy
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 06:20 pm
Der Kompiler könnte
Code: [Select]
struct x{
  uint32_t a;
  uint16_t b;
  uint8_t c;
};
struct y{
  uint32_t d;
  x e;
  uint16_t f;
};

in
Code: [Select]

struct y{
  uint32_t d;
  uint32_t e.a;
  uint16_t e.b;
  uint8_t e.c;
  uint16_t f;
};

umformen und dann alles nach Größe ordnen, sodass
Code: [Select]

struct y{
  uint32_t d;
  uint32_t e.a;
  uint16_t e.b;
  uint16_t f;
  uint8_t e.c;
};

rauskommt. Da kann er sich, glaube ich, immer über die Entscheidung des Programmierers hinwegsetzen, denn der hat ja wahrscheinlich nichts gegen Optimierung. Schießlich optimieren Kompiler ja auchden Assembler-Code. Wenn das mal nicht der Fall sein sollte, könnte man sich doch ein schlaues Keyword wie "keep" oder so ausdenken und das setzt man einfach irgendwo in die Deklaration ein.
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 06:29 pm
Darf er nicht, denn Du hast ihm mitgeteilt, dass Du auf e getrennt zugreifen willst. Deshalb muss e zusammen bleiben, weil Du es so gewollt hast.

Gruß Tommy
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 06:30 pm
Wie kann ich ihm mitteilen, dass das nicht mein Plan ist?
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 06:41 pm
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
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: michael_x on May 19, 2020, 06:49 pm
Hatten wir doch schon in #pragma pack(1) (https://forum.arduino.cc/index.php?topic=685194.msg4608574#msg4608574) 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?)
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 06:51 pm
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?
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 06:52 pm
Argh!
Ich habe mir doch glatt die Antwort selber gegeben: Man kann es als Parameter mitgeben, also muss es ein zusammenhängender Haufen sein!  :smiley-confuse::smiley-red:
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 06:54 pm
Oder mehrere Haufen in mehreren Parametern.

Gruß Tommy
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: michael_x on May 19, 2020, 06:55 pm
Sei lieber froh, dass gelegentlich ein bool weniger als 32 bit braucht auf deinem ESP32 :)
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 06:57 pm
Sei lieber froh, dass gelegentlich ein bool weniger als 32 bit braucht auf deinem ESP32 :)
Ich bin nicht in der Lage, meine extreme Begeisterung in Worte zu fassen.
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 06:57 pm
@michael_x: Naja, man könnte ja 32 boolsche Werte in 32 Bit speichern ;)
Das hast Du aber sicher nicht gemeint.

Gruß Tommy
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: combie on May 19, 2020, 07:01 pm
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.
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 07:01 pm
@michael_x: Naja, man könnte ja 32 boolsche Werte in 32 Bit speichern ;)
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.
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 07:08 pm
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[]?
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 07:14 pm
Tipp:
Für ungenutzten Speicher, gibts kein Geld zurück.
Der Tipp ist sehr gut.

Gruß Tommy
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 07:21 pm
Ach ja: Ist uint32_t besser als int32_t, wenn es um Geschwindigkeit geht?
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: combie on May 19, 2020, 07:28 pm
Quote
Puh, hat sich die Welt seit dem 6502 weiterentwickelt. Ich weiß nicht, was ich davon halten soll.


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"


Quote
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).
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: combie on May 19, 2020, 07:46 pm
Nachtrag:

Du solltest dir evtl die Definition von Byte (https://de.wikipedia.org/wiki/Byte) mal durchlesen.
Das kann ein echter Augenöffner sein.

Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 07:50 pm
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.
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.
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 19, 2020, 07:58 pm
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
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: combie on May 19, 2020, 08:04 pm
Quote
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.
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Serenifly on May 19, 2020, 08:08 pm
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
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 08:15 pm
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?
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: combie on May 19, 2020, 08:31 pm
Risc Maschinen benötigen für eine Addition (in der Regel) nur einen Takt. (z.B. AVR,ARM,ESP)
Deine 8 Zyklen sind also eine kleine Ewigkeit.
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 19, 2020, 08:37 pm
Oh Gott! Und ich dachte immer, dass alle meine Berechnungen, was CPU-Geschwindigkeit angeht, totaler Schwachsinn sind, da + soviele Takte braucht, wie es Bits gibt.

Gut, das Ergebnis ist also, dass man bei einem ESP32, wenn man nicht gerade riesige Arrays hat, immer int32_t (oder doch uint32_t?) nehmen sollte.

Noch zum Schluss eine Frage:
Ich habe momentan meine Partikel-Liste in etwa so:
Code: [Select]

struct Particle {
  int32_t x, y;
  int16_t xV, yV;
  uint8_t time = 255;
};
Particle particles[xyz]

Würde es stattdessen Sinn machen,
Code: [Select]

int32_t x[xyz];
int32_t y[xyz];
int16_t xV[xyz];
int16_t yV[xyz];
uint8_t time[xyz];

zu nutzen? Ich habe mehrere tausend Partikel, deswegen muss das bei int16_t und uint8_t bleiben.
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: michael_x on May 20, 2020, 12:51 pm
Dem Compiler ist es egal. Vermutlich ist die Komma-Schreibweise übersichtlicher für dich, weil sie zusammenfasst, was zusammengehört.

Man kann es auch auf die Spitze treiben  ganz ordentlich machen und einen Datentyp
struct Position {int32_t x, y;};
definieren, und dann

Code: [Select]
struct Particle {
  Position pos;
  Speed speed;
  uint8_t time;
};

definieren.
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 20, 2020, 12:55 pm
Man kann es auch auf die Spitze treiben  ganz ordentlich machen und einen Datentyp
struct Position {int32_t x, y;};
definieren, und dann

Code: [Select]
struct Particle {
  Position pos;
  Speed speed;
  uint8_t time;
};

definieren.
Kann man. Aber ich habe mir angewöhnt, an Positionen ein großes V für velocity dranzuhängen. Doch jetzt, wo ich drüber nachdenke, ist das vielleicht doch nicht so blöd, dann kann man ja sowas wie
Code: [Select]
float calcSpeed(Speed speed){
  return sqrt(sq(speed.x) + sq(speed.y));
}

machen. Das ist gelebte OOP!
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 20, 2020, 03:42 pm
Wie sieht es den beim ESP32 mit uint32_t (unsigned int) aus? Kann das genauso schnell wie int32_t (int) verarbeitet werden?
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: Tommy56 on May 20, 2020, 03:44 pm
Dann überlege doch mal, was der Unterschied zwischen beiden ist.

Gruß Tommy
Title: Re: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr?
Post by: HTML-Fan on May 20, 2020, 03:47 pm
Das Vorzeichen bzw. seine Existenz. Ich denke mir, dass es schwieriger = zeitaufwändiger sein müsste, mit einem Vorzeichen zu rechnen. unsigned int + unsigned int wird, wenn ich mich gerade nicht völlig vertue, auf die selbe Art und Weise berechnet, aber bei anderen Befehlen könnte das anders sein.