Go Down

Topic: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr? (Read 988 times) previous topic - next topic

combie

Nachtrag:

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

Der Verstand, und die Fähigkeit ihn zu gebrauchen, sind zweierlei Fähigkeiten.

HTML-Fan

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.

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
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

combie

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.
Der Verstand, und die Fähigkeit ihn zu gebrauchen, sind zweierlei Fähigkeiten.

Serenifly

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

HTML-Fan

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?

combie

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.
Der Verstand, und die Fähigkeit ihn zu gebrauchen, sind zweierlei Fähigkeiten.

HTML-Fan

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.

michael_x

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.

HTML-Fan

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!

HTML-Fan

Wie sieht es den beim ESP32 mit uint32_t (unsigned int) aus? Kann das genauso schnell wie int32_t (int) verarbeitet werden?

Tommy56

Dann überlege doch mal, was der Unterschied zwischen beiden ist.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

HTML-Fan

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.

Go Up