it-swarm.com.de

Zweck der Speicherausrichtung

Zugegeben, ich verstehe es nicht. Angenommen, Sie haben ein Gedächtnis mit einem Gedächtniswort von 1 Byte Länge. Warum können Sie nicht auf eine 4 Byte lange Variable in einem einzigen Speicherzugriff auf eine nicht ausgerichtete Adresse zugreifen (d. H. Nicht durch 4 teilbar), wie dies bei ausgerichteten Adressen der Fall ist?

171
ark

Dies ist eine Einschränkung vieler zugrunde liegender Prozessoren. Es kann normalerweise umgangen werden, indem 4 ineffiziente Einzelbyte-Abrufe anstatt eines effizienten Word-Abrufs durchgeführt werden. Viele Sprachspezifizierer entschieden jedoch, dass es einfacher wäre, sie einfach zu verbieten und alles zum Ausrichten zu zwingen.

Es gibt viel mehr Informationen in dieser Link die das OP entdeckt hat.

56
Paul Tomblin

Das Speichersubsystem eines modernen Prozessors beschränkt sich auf den Zugriff auf den Speicher mit der Granularität und Ausrichtung seiner Wortgröße. Dies ist aus mehreren Gründen der Fall.

Geschwindigkeit

Moderne Prozessoren verfügen über mehrere Cache-Speicherebenen, durch die Daten abgerufen werden müssen. Durch die Unterstützung von Einzelbyte-Lesevorgängen wird der Durchsatz des Speichersubsystems eng an den Durchsatz der Ausführungseinheit gebunden (auch bekannt als CPU-gebunden). Dies alles erinnert daran, wie PIO-Modus wurde von DMA übertroffen aus vielen der gleichen Gründe in Festplatten.

Die CPU liest immer mit ihrer Wortgröße (4 Bytes auf einem 32-Bit-Prozessor), also wenn Sie einen nicht ausgerichteten Adressenzugriff ausführen - auf einem Prozessor, der unterstützt es - der Prozessor liest mehrere Wörter. Die CPU liest jedes Wort des Speichers, das Ihre angeforderte Adresse überspannt. Dies führt zu einer Vervielfachung der Anzahl der Speichertransaktionen, die für den Zugriff auf die angeforderten Daten erforderlich sind.

Aus diesem Grund kann es sehr leicht langsamer sein, zwei Bytes als vier zu lesen. Angenommen, Sie haben eine Struktur im Speicher, die folgendermaßen aussieht:

struct mystruct {
    char c;  // one byte
    int i;   // four bytes
    short s; // two bytes
}

Auf einem 32-Bit-Prozessor würde es höchstwahrscheinlich wie hier gezeigt ausgerichtet sein:

Struct Layout

Der Prozessor kann jedes dieser Mitglieder in einer Transaktion lesen.

Nehmen wir an, Sie hatten eine gepackte Version der Struktur, möglicherweise aus dem Netzwerk, in das sie für die Übertragungseffizienz gepackt wurde. es könnte ungefähr so ​​aussehen:

Packed Struct

Das Lesen des ersten Bytes wird dasselbe sein.

Wenn Sie den Prozessor auffordern, Ihnen 16 Bit von 0x0005 zu geben, muss er ein Wort von 0x0004 lesen und 1 Byte nach links verschieben, um es in ein 16-Bit-Register zu legen. etwas mehr Arbeit, aber die meisten schaffen das in einem Zyklus.

Wenn Sie bei 0x0001 nach 32 Bit fragen, erhalten Sie eine zweifache Verstärkung. Der Prozessor liest von 0x0000 in das Ergebnisregister und verschiebt 1 Byte nach links, dann erneut von 0x0004 in ein temporäres Register, verschiebt 3 Byte nach rechts und dann OR mit dem Ergebnisregister.

Reichweite

Wenn die Architektur für einen bestimmten Adressraum davon ausgehen kann, dass die 2 LSBs immer 0 sind (z. B. 32-Bit-Maschinen), kann sie auf das 4-fache des Speichers zugreifen (die 2 gespeicherten Bits können 4 verschiedene Zustände darstellen) oder auf dieselbe Menge Speicher mit 2 Bits für so etwas wie Flags. Wenn Sie die 2 LSBs von einer Adresse entfernen, erhalten Sie eine 4-Byte-Ausrichtung. auch als Schritt von 4 Bytes bezeichnet. Jedes Mal, wenn eine Adresse inkrementiert wird, wird Bit 2 und nicht Bit 0 effektiv inkrementiert, d. H., Die letzten 2 Bits bleiben immer 00.

Dies kann sogar das physikalische Design des Systems beeinflussen. Wenn der Adressbus 2 Bits weniger benötigt, können 2 Pins weniger auf der CPU und 2 Leiterbahnen weniger auf der Leiterplatte vorhanden sein.

Atomarität

Die CPU kann ein ausgerichtetes Wort des Speichers atomar bearbeiten, was bedeutet, dass kein anderer Befehl diesen Vorgang unterbrechen kann. Dies ist entscheidend für den korrekten Betrieb vieler sperrenfreier Datenstrukturen und anderer Parallelität Paradigmen.

Fazit

Das Speichersystem eines Prozessors ist wesentlich komplexer und komplexer als hier beschrieben. Eine Diskussion über wie ein x86-Prozessor den Speicher tatsächlich adressiert kann helfen (viele Prozessoren arbeiten ähnlich).

Die Einhaltung der Speicherausrichtung bietet noch viele weitere Vorteile, die Sie unter dieser IBM Artikel lesen können.

Der Hauptzweck eines Computers ist die Umwandlung von Daten. Moderne Speicherarchitekturen und -technologien wurden über Jahrzehnte hinweg optimiert, um mehr Daten in und zwischen mehr und schnelleren Ausführungseinheiten auf höchst zuverlässige Weise zu erhalten.

Bonus: Caches

Eine andere Ausrichtung für die Leistung, auf die ich zuvor angespielt habe, ist die Ausrichtung auf Cache-Zeilen, die (zum Beispiel auf einigen CPUs) 64B betragen.

Weitere Informationen dazu, wie viel Leistung durch die Nutzung von Caches erzielt werden kann, finden Sie unter Galerie der Prozessor-Cache-Effekte ; von diesem Frage zu Cache-Zeilengrößen

Das Verständnis der Cache-Zeilen kann für bestimmte Arten von Programmoptimierungen wichtig sein. Beispielsweise kann die Ausrichtung von Daten bestimmen, ob eine Operation eine oder zwei Cache-Zeilen berührt. Wie wir im obigen Beispiel gesehen haben, kann dies leicht bedeuten, dass der Vorgang im fehlausgerichteten Fall zweimal langsamer ist.

281
joshperry

sie können mit einigen Prozessoren ( die Nehalem können dies tun ), aber zuvor war der gesamte Speicherzugriff auf einer 64-Bit- (oder 32-Bit-) Leitung ausgerichtet, da der Bus 64 Bit breit ist, den Sie hatten 64 Bit gleichzeitig abzurufen, und es war bedeutend einfacher, diese in ausgerichteten "Stücken" von 64 Bit abzurufen.

Wenn Sie also ein einzelnes Byte abrufen möchten, haben Sie den 64-Bit-Block abgerufen und dann die nicht gewünschten Bits ausgeblendet. Einfach und schnell, wenn sich Ihr Byte am richtigen Ende befand, aber wenn es sich in der Mitte dieses 64-Bit-Blocks befand, müssten Sie die unerwünschten Bits maskieren und die Daten dann an die richtige Stelle verschieben. Schlimmer noch, wenn Sie eine 2-Byte-Variable wollten, die jedoch auf 2 Blöcke aufgeteilt wurde, waren doppelt so viele Speicherzugriffe erforderlich.

Da jeder der Meinung ist, dass Speicher billig ist, hat er den Compiler lediglich dazu gebracht, die Daten an den Chunk-Größen des Prozessors auszurichten, damit Ihr Code schneller und effizienter ausgeführt werden kann.

22
gbjbaanb

Grundsätzlich liegt der Grund darin, dass der Speicherbus eine bestimmte Länge hat, die viel, viel kleiner als die Speichergröße ist.

Die CPU liest also aus dem auf dem Chip befindlichen L1-Cache, der heutzutage häufig 32 KB groß ist. Der Speicherbus, der den L1-Cache mit der CPU verbindet, hat jedoch die erheblich geringere Breite der Cache-Zeilengröße. Dies wird in der Größenordnung von 128 Bits liegen.

So:

262,144 bits - size of memory
    128 bits - size of bus

Falsch ausgerichtete Zugriffe überlappen gelegentlich zwei Cache-Zeilen, und dies erfordert ein völlig neues Lesen des Cache, um die Daten zu erhalten. Es könnte sogar bis zum DRAM fehlen.

Darüber hinaus muss ein Teil der CPU auf dem Kopf stehen, um aus diesen zwei verschiedenen Cache-Zeilen, die jeweils einen Teil der Daten enthalten, ein einzelnes Objekt zusammenzusetzen. In einer Zeile sind es die Bits sehr hoher Ordnung, in der anderen die Bits sehr niedriger Ordnung.

Es wird dedizierte Hardware geben, die vollständig in die Pipeline integriert ist und das Verschieben ausgerichteter Objekte auf die erforderlichen Bits des CPU-Datenbusses handhabt. Bei falsch ausgerichteten Objekten kann diese Hardware jedoch fehlen, da es wahrscheinlich sinnvoller ist, diese Transistoren zur Beschleunigung richtig optimiert zu verwenden Programme.

In jedem Fall würde der zweite Speicherlesevorgang, der manchmal erforderlich ist, die Pipeline verlangsamen, unabhängig davon, wie viel Spezialhardware (hypothetisch und törichterweise) für das Korrigieren falsch ausgerichteter Speicheroperationen verwendet wurde.

4
DigitalRoss

@joshperry hat diese Frage hervorragend beantwortet. Zusätzlich zu seiner Antwort habe ich einige Zahlen, die die beschriebenen Effekte grafisch darstellen, insbesondere die 2-fache Verstärkung. Hier ist ein Link zu einer Google-Tabelle , die zeigt, wie sich die verschiedenen Word-Ausrichtungen auswirken. Außerdem ist hier ein Link zu einem Github Gist mit dem Code für den Test. Der Testcode ist angepasst an den Artikel von Jonathan Rentzsch, auf den @joshperry verwiesen hat. Die Tests wurden auf einem Macbook Pro mit einem Vierkern-Intel Core i7 64-Bit-Prozessor mit 2,8 GHz und 16 GB RAM durchgeführt.

enter image description here

3
adino

Wenn ein System mit byteadressierbarem Speicher über einen 32 Bit breiten Speicherbus verfügt, bedeutet dies, dass es effektiv vier byteweite Speichersysteme gibt, die alle zum Lesen oder Schreiben derselben Adresse verdrahtet sind. Ein ausgerichtetes 32-Bit-Lesen erfordert Informationen, die in allen vier Speichersystemen unter derselben Adresse gespeichert sind, sodass alle Systeme gleichzeitig Daten liefern können. Bei einem nicht ausgerichteten 32-Bit-Lesevorgang müssten einige Speichersysteme Daten von einer Adresse und einige Daten von der nächsthöheren Adresse zurückgeben. Obwohl es einige Speichersysteme gibt, die so optimiert sind, dass sie solche Anforderungen erfüllen können (zusätzlich zu ihrer Adresse haben sie effektiv ein "plus eins" -Signal, wodurch sie eine Adresse verwenden, die um eins höher als angegeben ist), verursacht ein solches Merkmal erhebliche Kosten und Komplexität eines Speichersystems; Die meisten Commodity-Speichersysteme können einfach nicht Teile verschiedener 32-Bit-Wörter gleichzeitig zurückgeben.

2
supercat

Wenn Sie einen 32-Bit-Datenbus haben, beginnen die Adressleitungen des Adressbusses, die mit dem Speicher verbunden sind, bei A2In einem einzigen Buszyklus kann also nur auf 32-Bit-ausgerichtete Adressen zugegriffen werden.

Also, wenn ein Wort eine Adressausrichtungsgrenze überspannt - d. H. A für 16/32 Bit Daten oder A1 Für 32-Bit-Daten, die nicht Null sind, sind zwei Buszyklen erforderlich, um die Daten zu erhalten.

Einige Architekturen/Befehlssätze unterstützen keinen nicht ausgerichteten Zugriff und generieren bei solchen Versuchen eine Ausnahme. Daher erfordert der vom Compiler generierte nicht ausgerichtete Zugriffscode nicht nur zusätzliche Buszyklen, sondern auch zusätzliche Anweisungen, wodurch er noch weniger effizient wird.

1
Clifford

Auf einem PowerPC können Sie problemlos eine Ganzzahl von einer ungeraden Adresse laden.

Sparc und I86 und (ich denke) Itatnium lösen Hardware-Ausnahmen aus, wenn Sie dies versuchen.

Eine 32-Bit-Last im Vergleich zu vier 8-Bit-Lasten macht auf den meisten modernen Prozessoren keinen großen Unterschied. Ob sich die Daten bereits im Cache befinden oder nicht, hat weitaus größere Auswirkungen.

0
James Anderson