![ein Kapitel weiter](../weiter.gif)
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](struct4.png)
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 weiter](../weiter.gif)
© 2001,2002 Jürgen Wolf
|