ein Kapitel zurück                                           ein Kapitel weiter

Damit der Rechner schneller auf Daten im Hauptspeicher zugreifen kann ordnet er diese in zwei oder vier, Teilbare Adressen an (je nach System 16 oder 32 bit). Das Problem ist im Fall von Strukuturen, das Speicherplatzt verschenkt wird, da die Datentypen nicht sauber hintereinander plaziert werden. Zur Demonstration können sie diese Programm testen.....

/*Download:align1.c*/
#include <stdio.h> struct speicher{ char x; int z; }; int main() { struct speicher test; printf("%ld Bytes\n",sizeof(test)); return 0; }

Sie werden als Ausgabe 8 Bytes erhalten?! Obwohl eigentlich nur 5 (3) Bytes, char (1 Byte) + int (4 Bytes(oder 2Bytes)) = 5(3) Bytes. Bei mir auf einem Linux-Rechner, benötigt die Struktur 8 Bytes. Somit ergibt sich folgendes Bild....


Alignment


Hier sehen sie ein 4 Byte-Alignment, wie es fast bei jedem der Fall sein dürfte (32bit). Es werden also 3 Bytes verschenkt. In einer grossen Datenbank ist dies nicht zu Aktzeptieren.

Um das Problem zu lösen gibt es für viele Compiler einen speziellen Schalter. Wobei man gleich anmerken muss, dass dies nicht ANSI-C Konform ist. Ich Demonstriere es Ihnen hier anhand des gcc-Compilers.

Mit.......

__attribut__

...haben sie die Möglichkeit dem gcc mehr Informationen, zu einer Funktion, Variable oder Datentypen zu geben. Und um lückenlose Speicherbelegung zu erreichen, können sie das Attribut packed verwenden.....

/*Download:align2.c*/
#include <stdio.h> struct speicher{ char x; int z; } __attribute__ ((packed)); int main() { struct speicher test; printf("%ld Bytes\n",sizeof(test)); return 0; }

Übersetzen sie das Programm erneut und nun benötigt unsere Struktur tatsächlich 5 Bytes. Das ganze funktioniert natürlich auch bei enum-Aufzählungen.....

/*Download:align3.c*/
#include <stdio.h> enum{TRUE,FALSE} __attribute__ ((packed)); int main() { printf("%ld Bytes\n",sizeof(TRUE)); return 0; }

In diesem Fall wird durch packed ein 1-Byte-Alignment angelegt. Das ist gegenüber 4 Bytes ohne packed beachtlich. Diese Werte können natürlich von System zu System anders sein.

Etwas irritierend ist, wenn sie man gcc aufrufen das Attribut aligned. Dieses Attribut legt fest wie eine Variable oder Datenstruktur im Speicher angeordnet wird. Beispielsweise......

/*Download:align4.c*/
#include <stdio.h> struct speicher{ char x; int z; } __attribute__ ((aligned)); int main() { struct speicher test; printf("%ld Bytes\n",sizeof(test)); return 0; }

Dadurch wird jedem Datentypen eine Größe von 8 Bytes reserviert.

Bei den Vorteilen die sie mit packed erzielen sollten sie vielleicht auch die Nachteil bedenken! Wenn sie diese Daten (struct speicher) auf Ihrem System mit 5 Bytes pro Struktur speichern, kann es passieren das diese Daten auf einem anderen System falsch angezeigt werden, da das Programm dort nicht mit der Option packed übersetzt wurde. Außerdem könnten Low-Level-Funktionen fehlschlagen, da sich die Daten, wegen des Alignment, nicht dort befinden wo sie diese Funktionen eigentlich vermuten.

Und da wir schon bei dem Setzen von Attributen sind wollen wir es gleich ausnutzen mehr zu lernen (ist nicht allzu wichtig für den weiteren Verlauf des Kurses).

Beispielsweise wenn sie einen int-Wert (Wortgröße) auf einem System mit einem 68040-Prozessor übersetzen, benötigen sie für einen Assembler-Ausdruck, move 16, ein 16 Byte großen int-Wert (16-Byte-Alignment). Dabei gehen sie wie folgt vor........

/*Download:align5.c*/
#include <stdio.h> int big_int __attribute__ ((aligned(16))); int main() { printf("%ld Bytes\n",sizeof(big_int)); return 0; }

Schon haben wir ein 16 Byte-Alignment. Damit wird auf einem Rechner mit einem 68040-Prozessor, für den Datentyp big_int 16 Bytes Speicher reserviert. Sollten sie diese Arbeit dem Compiler machen lassen wie Beispielsweise bei short-Werten.....

short x[3] __attribute__ ((aligned));

...verwendet der Compiler die größte Größe die er für diesen Datentypen kennt. Dies war nur ein kleiner und kurzer Überblick zu diesem Thema. Ich empfehle Ihnen die Dokumentation des gcc-Compilers darüber zu lesen.

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf