Ausrichtungseinschränkungen für malloc () / free ()

8

Ältere K & amp; R (2. Aufl.) und andere C-sprachige Texte, die ich gelesen habe und die die Implementierung eines dynamischen Speicherzuordners im Stil von malloc() und free() diskutieren, erwähnen nebenbei auch etwas darüber Beschränkungen für die Ausrichtung von Daten. Anscheinend beschränken bestimmte Computer-Hardware-Architekturen (CPU, Register und Speicherzugriff), wie Sie bestimmte Werttypen speichern und adressieren können. Zum Beispiel kann es erforderlich sein, dass eine Ganzzahl von 4 Byte ( long ) beginnend bei Adressen, die Vielfache von vier sind, gespeichert werden muss.

Welche Einschränkungen, wenn überhaupt, werden von großen Plattformen (Intel & AMD, SPARC, Alpha) für die Speicherzuweisung und den Speicherzugriff auferlegt, oder kann ich die Zuordnung von Speicherzuweisungen an bestimmten Adressgrenzen ignorieren?

    
Richard Chambers 30.08.2008, 23:07
quelle

5 Antworten

6

Sparc, MIPS, Alpha und die meisten anderen "klassischen RISC" -Architekturen erlauben nur ausgerichtete Zugriffe auf den Speicher, auch heute noch. Ein nicht ausgerichteter Zugriff verursacht eine Ausnahme, aber einige Betriebssysteme verarbeiten die Ausnahme, indem sie von der gewünschten Adresse in Software mit kleineren Lasten und Speichern kopieren. Der Anwendungscode weiß nicht, dass ein Problem aufgetreten ist, außer dass die Leistung sehr schlecht ist.

MIPS verfügt über spezielle Anweisungen (lwl und lwr), die verwendet werden können, um auf 32-Bit-Mengen von nicht ausgerichteten Adressen zuzugreifen. Wann immer der Compiler feststellen kann, dass die Adresse wahrscheinlich nicht ausgerichtet ist, wird er diese zwei Befehlssequenzen anstelle einer normalen lw-Anweisung verwenden.

x86 kann nicht ausgerichtete Speicherzugriffe in Hardware ohne Ausnahme handhaben, aber es gibt immer noch einen Leistungseinbruch von bis zu drei Mal im Vergleich zu ausgerichteten Zugriffen.

Ulrich Drepper hat ein umfassendes Papier zu diesem Thema und anderen erinnerungsbezogenen Themen geschrieben, Was jeder Programmierer über den Speicher wissen sollte . Es ist eine sehr lange Beschreibung, aber gefüllt mit zäher Güte.

    
DGentry 06.09.2008 05:57
quelle
4

Die Ausrichtung ist heute noch sehr wichtig. Einige Prozessoren (die 68k-Familie springt einem in den Sinn) würden eine Ausnahme auslösen, wenn Sie versuchen würden, auf einen Wortwert an einer ungeraden Grenze zuzugreifen. Heutzutage werden die meisten Prozessoren zwei Speicherzyklen ausführen, um ein nicht ausgerichtetes Wort zu holen, aber dies wird definitiv langsamer sein als ein ausgerichteter Abruf. Einige andere Prozessoren werden nicht einmal eine Ausnahme auslösen, sondern einen falschen Wert aus dem Speicher holen!

Wenn es aus keinem anderen Grund als der Leistung ist, sollten Sie versuchen, den Ausrichtungspräferenzen Ihres Prozessors zu folgen. Normalerweise kümmert sich Ihr Compiler um alle Details, aber wenn Sie etwas tun, bei dem Sie die Speicherstruktur selbst anlegen, dann ist es eine Überlegung wert.

    
Greg Hewgill 30.08.2008 23:11
quelle
1

Sie müssen beim Erstellen einer Klasse oder Struktur in C (++) immer noch auf Ausrichtungsprobleme achten. In diesen Fällen wird der Compiler das Richtige für Sie tun, aber die Gesamtgröße der Struktur / Klasse kann verschwenderischer als nötig sein.

Zum Beispiel:

%Vor%

Hätte eine Größe von 4 * 4 = 16 Bytes (angenommen Windows auf x86), während

%Vor%

Würde eine Größe von 4 * 3 = 12 Bytes haben.

Dies liegt daran, dass der Compiler eine 4-Byte-Ausrichtung für Ganzzahlen erzwingt, aber nur 1 Byte für Zeichen.

Im Allgemeinen Pack-Element-Variablen der gleichen Größe (Typ) zusammen zu minimieren verschwendeten Raum.

    
Rob Walker 30.08.2008 23:22
quelle
1

Wie Greg bereits erwähnt hat, ist es immer noch wichtig (vielleicht in gewisser Weise) und Compiler kümmern sich normalerweise um die Ausrichtung, die auf dem Ziel der Architektur basiert. In verwalteten Umgebungen kann der JIT-Compiler die Ausrichtung basierend auf der Laufzeitarchitektur optimieren.

Möglicherweise sehen Sie Pragma-Direktiven (in C / C ++), die die Ausrichtung ändern. Dies sollte nur verwendet werden, wenn eine sehr spezifische Ausrichtung erforderlich ist.

%Vor%     
denis phillips 31.08.2008 01:32
quelle
1

Beachten Sie, dass selbst bei IA-32 und AMD64 einige der SSE-Anweisungen / Intrinsics ausgerichtete Daten erfordern. Diese Anweisungen werden eine Ausnahme auslösen, wenn die Daten nicht ausgerichtet sind, so dass Sie zumindest keine "falschen Daten" -Bugs debuggen müssen. Es gibt auch entsprechende nicht ausgerichtete Anweisungen, aber wie Denton sagt, sind sie langsamer.

Wenn Sie VC ++ verwenden, verfügen Sie neben den #pragma pack-Anweisungen auch über die __declspec (align) -Direktiven für die präzise Ausrichtung. Die VC ++ - Dokumentation erwähnt auch eine __aligned_malloc-Funktion für bestimmte Ausrichtungsanforderungen.

Als Faustregel gilt: Wenn Sie Daten nicht über Compiler / Sprachen verschieben oder die SSE-Anweisungen verwenden, können Sie Ausrichtungsprobleme wahrscheinlich ignorieren.

    
Pramod 06.09.2008 06:19
quelle

Tags und Links