Padding Bytes in Byte struct



  • @Bushmaster sagte in Padding Bytes in Byte struct:

    @hustbaer sagte in Padding Bytes in Byte struct:

    Auf solchen Systemen darf es - wenn ich das alles richtig verstehe - sowieso kein uint8_t geben. Wegen memory model und so.

    das könnte ja die cpu übernehmen.
    angenommen byte-adresse 123 soll geschrieben werden. dann lädt die cpu das 16-bit-wort von word-adresse 61 ändert das low-byte und schreibt das wort wieder in den speicher. für den asm-programmierer ist das eine atomare operation, die bloß mehr taktzyklen braucht als ein 16-bit-schreibzugriff.

    Solche Systeme kenne ich nicht und AFAIK gibt es auch keine aktuellen solchen die irgendwie relevant wären. Alles was ich kenne was auf Assemblerebene direkt 8-Bit Bytes adressieren kann, kann entweder auch ohne "read-modify-write" direkt 8 Bit breit auf den Hauptspeicher zugreifen -- oder es hat einen Datencache dazwischen der sowieso immer ganze Cache-Lines aus dem Hauptspeicher liest und irgendwann wieder zurückschreibt.

    Und bei den Systemen mit Datencache bleibt es dann auch egal ob du 8, 16 oder 32 Bit schreibst, weil die Cache-Lines nochmal deutlich breiter sind. Daher muss - wenn die Cache-Line nicht schon im Cache liegt - diese immer erst geladen werden bevor der geschriebene Wert hineingestanzt werden kann. Dazu haben solche CPUs dann üblicherweise sog. Store-Buffer, so dass sie mit der Bearbeitung des nächsten Befehls nicht warten müssen bis die Cache-Line geladen wurde und der Wert dort eingesetzt ist. Und auf das Zurückschreiben wird typischerweise sowieso nicht gewartet. Das passiert dann wenn es sein muss. z.B. wenn eine andere CPU/ein anderer Core die selbe Cache-Line haben möchte.

    Daher bin ich einfach davon ausgegangen dass @DirkB Systeme meint wo man wirklich mehrere Assemblerbefehle dazu braucht und das ganze nicht mehr atomar ist.


    Aber selbst wenn wir annehmen wir hätten so ein System. Dann wäre es IMO irgendwie komisch auf der einen Seite uint8_t anzubieten, was das arbeiten mit uint8_t Arrays recht langsam machen würde. Aber auf der anderen Seite dann Padding in Structs einzufügen, damit es in den Structs schneller geht.

    Padding zwischen mehreren direkt benachbarten uint8_t in einem Struct einzufügen ist für mich etwas was so grenzwertig beknackt ist, dass es vermutlich verschmerzbar ist wenn man es nicht berücksichtigt. Ich bin aber i.A. kein Fan von solchen Annahmen. Daher würde ich selbst bei dieser Annahme eine static Assertion oder notfalls einen Test schreiben so dass sichergestellt ist dass man mitbekommt wenn sie mal nicht mehr zutrifft. Aber ich würde niemand gröber beschimpfen nur weil er es nicht tut 🙂



  • @hustbaer sagte in Padding Bytes in Byte struct:

    Solche Systeme kenne ich nicht und AFAIK gibt es auch keine aktuellen solchen die irgendwie relevant wären.

    es geht noch schlimmer. bei einigen signalprozessoren ist jeder speicherzugriff immer 32bittig. erhöht man eine adresse um 1, ist man gleich 4 bytes weiter. 🙂

    The C operation sizeof returns very different results on the C3x/C4x than on traditional RISC/CISC processors. The sizeof(char), sizeof(short), and sizeof(int) are all 1 since each occupies a single addressable unit that is thirty-two bits wide.

    https://docs.rtems.org/releases/rtemsdocs-4.6.99.3/share/rtems/html/supplements/c4x/c4x00017.html



  • @Bushmaster sagte in Padding Bytes in Byte struct:

    bei einigen signalprozessoren ist jeder speicherzugriff immer 32bittig.

    Aber gerade die sind doch darauf spezialisiert Datenfolgen zu verarbeiten.



  • @Bushmaster sagte in Padding Bytes in Byte struct:

    ist man gleich 4 bytes weiter.

    Ne, Du bist 1 Byte weiter. </nitpickin>



  • @Swordfish sagte in Padding Bytes in Byte struct:

    @Bushmaster sagte in Padding Bytes in Byte struct:

    ist man gleich 4 bytes weiter.

    Ne, Du bist 1 Byte weiter. </nitpickin>

    ich hätte wohl octets schreiben sollen. 😉
    https://en.wikipedia.org/wiki/Octet_(computing)



  • @Bushmaster sagte in Padding Bytes in Byte struct:

    @hustbaer sagte in Padding Bytes in Byte struct:

    Solche Systeme kenne ich nicht und AFAIK gibt es auch keine aktuellen solchen die irgendwie relevant wären.

    es geht noch schlimmer. bei einigen signalprozessoren ist jeder speicherzugriff immer 32bittig. erhöht man eine adresse um 1, ist man gleich 4 bytes weiter. 🙂

    Ich weiss. Dann sind wir wieder bei meinem Beitrag von 18:52 und Systemen die vermutlich gar keinen uint8_t haben weil er nicht vernünftig umsetzbar ist.

    Auf den du "das könnte ja die cpu übernehmen" geantwortet hast. Dann hab ich dir erklärt dass Systeme wo die CPU das übernimmt kein Problem sind weil die Zugriffe dort typischerweise nicht langsam sind. Worauf du jetzt zu den Systemen zurückgehst die wir bereits abgehakt hatten (wo die CPU es eben nicht kann) und so tust als wäre das jetzt was neues was ich nicht bedacht hatte.

    Mit dir zu diskutieren ist echt anstrengend und manchmal kommt es mir so vor als ob du absichtlich trollst. Dann wieder nicht. Und dann wieder schon. Soll sich mal einer auskennen.



  • @DirkB sagte in Padding Bytes in Byte struct:

    @Bushmaster sagte in Padding Bytes in Byte struct:

    bei einigen signalprozessoren ist jeder speicherzugriff immer 32bittig.

    Aber gerade die sind doch darauf spezialisiert Datenfolgen zu verarbeiten.

    DSPs können oft nur einen einzigen Datentyp laden/bearbeiten/speichern. Die sind dann aber auch selten das Ziel einer vollständigen und standardkonformen C11, C18 oder gar C++ Implementierung.

    Und selbst bei DSPs die eher Features wie modernes SIMD Gedöns haben, mit unzähligen pack/unpack/shuffle Befehlen, wird man da kaum mit normalen (u)intXX_t Typen und Zeiger arbeiten. Sondern wie beim SIMD Gedöns spezielle Intrinsics für diese pack/unpack/shuffle Operationen verwenden. Wo dann wieder eigene Regeln gelten bezüglich Alignment, Atomizität etc.



  • @hustbaer sagte in Padding Bytes in Byte struct:

    Mit dir zu diskutieren ist echt anstrengend und manchmal kommt es mir so vor als ob du absichtlich trollst. Dann wieder nicht. Und dann wieder schon. Soll sich mal einer auskennen.

    vielleicht fühlst du dich angegriffen, weil du glaubst ich versuche dich zu widerlegen? ich sehe das aber nicht als streitgespräch. was ich schreibe ist als ergänzung gemeint. nichts für ungut. 🙂



  • @hustbaer sagte in Padding Bytes in Byte struct:

    Padding zwischen mehreren direkt benachbarten uint8_t in einem Struct einzufügen ist für mich etwas was so grenzwertig beknackt ist, dass es vermutlich verschmerzbar ist wenn man es nicht berücksichtigt. Ich bin aber i.A. kein Fan von solchen Annahmen. Daher würde ich selbst bei dieser Annahme eine static Assertion oder notfalls einen Test schreiben so dass sichergestellt ist dass man mitbekommt wenn sie mal nicht mehr zutrifft. Aber ich würde niemand gröber beschimpfen nur weil er es nicht tut 🙂

    Ohne Frage ist das ziemlich ungewöhnlich, aber solange die Norm nicht entsprechende Zusagen macht, sollte man solche Hypothesen über das Verhalten von Plattformen unterlassen. Früher oder später knallt das, weil irgend jemand meinte C Compiler müssten sich so verhalten, weil das bisher alle getan haben, die er kennt.

    P.S. UNIX (die offizielle API Definition aus der Single UNIX Spec) verlangt, dass ein System 8Bit chars hat und die anderen Datentypen 16, 32 und 64Bit groß sind, und macht weitere Vorgaben für das Verhalten von Systemen. Wenn man ein Programm explizit für UNIX/Linux schreibt, kann etliche Annahmen machen, weil das eben der Standard für das OS so vorsieht. Weil auf fast jeder neuen Plattform ein UNIX/Linux zuerst läuft, ist es sehr unwahrscheinlich geworden, dass ein System sich nicht daran hält, und sich andere OS auch so verhalten werden. Aber für hosted Compiler sieht die Sache nun einmal anders aus.

    Nur wenn man solche zusätzliche Annahmen macht, schreibt man eben ein Programm für UNIX oder Windows und nicht mehr ein C Programm für eine beliebige Plattform. Die Routinen lassen sich dann auch nicht mehr ohne umfangreiche Prüfung portieren.

    Früher gab es aber Systeme die 9Bit chars hatten und dann 18 bzw. 36Bit für die anderen Datentypen. IBMs alten AS/400 hatten einen 48Bit Prozessor verbaut, bis dann die 64Bit PowerPCs für AS/400 kamen.



  • @john-0 sagte in Padding Bytes in Byte struct:

    Ohne Frage ist das ziemlich ungewöhnlich, aber solange die Norm nicht entsprechende Zusagen macht, sollte man solche Hypothesen über das Verhalten von Plattformen unterlassen.

    👏