Frage

Zwar bekomme ich es nicht. Sagen Sie bitte einen Speicher mit einem Speicherwort mit einer Länge von 1 Byte haben. Warum können nicht auf Sie eine 4-Byte lange Variable in einem einzigen Speicherzugriff auf einer nicht ausgerichtete Adresse (d. Nicht durch 4 teilbar), wie es der Fall mit ausgerichteten Adressen ist?

War es hilfreich?

Lösung

Es ist eine Einschränkung vieler zugrunde liegenden Prozessoren. Es kann in der Regel arbeitet rund um durch tun 4 ineffizient einzelnes Byte holt, anstatt ein effizientes Wort holen, aber viele Sprachbezeich beschlossen, es wäre einfacher, nur ächten sie und zwingt alles ausgerichtet werden.

Es gibt viel mehr Informationen in Link , dass der OP entdeckt.

Andere Tipps

Das Speichersubsystem auf einem modernen Prozessor beschränkt Speicher an der Granularität und Ausrichtung seiner Wortgröße für den Zugriff auf; dies ist der Fall für eine Reihe von Gründen.

Geschwindigkeit

Moderne Prozessoren haben mehrere Ebenen von Cache-Speicher, die Daten durch gezogen werden müssen; Einbyte- Stütz liest würde das Speichersubsystem Durchsatz fest gebunden an die Ausführungseinheit Durchsatz (auch bekannt als CPU-bound) bilden; das ist alles erinnert an wie PIO-Modus von DMA übertroffen wurde für viele der gleichen Gründen in Festplatten.

Die CPU immer bei seiner Wortgröße liest (4 Byte auf einem 32-Bit-Prozessor), so dass, wenn Sie einen nicht ausgerichteten Adresse Zugang zu tun - auf einem Prozessor, die es unterstützt - der Prozessor wird zu mehrere Wörter lesen. Die CPU wird jedes Wort von dem Speicher gelesen, dass Ihre Wunsch-Adresse spreizt. Dies führt zu einer Verstärkung von bis zu 2 × die Anzahl der Speicher-Transaktionen erforderlich, um die angeforderten Daten zugreifen zu können.

Aus diesem Grunde kann es sehr leicht langsamer zwei Bytes zu lesen als vier. Zum Beispiel, sagen Sie haben eine Struktur im Speicher, die wie folgt aussieht:

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

Auf einem 32-Bit-Prozessor wäre es höchstwahrscheinlich, wie hier gezeigt ausgerichtet werden:

Struct Layout

Der Prozessor kann jedes dieser Elemente in einer einzigen Transaktion lesen.

Angenommen, Sie hatten eine gepackte Version der Struktur, vielleicht aus dem Netzwerk, in dem es für die Übertragungseffizienz verpackt wurde; es könnte wie folgt aussehen:

Packed Struct

Lesen das erste Byte wird das gleiche sein.

Wenn Sie den Prozessor fragen Sie 16 Bits von 0x0005 zu geben, wird es ein Wort aus von 0x0004 und verschieben links 1 Byte platzieren es in einem 16-Bit-Register lesen müssen; einige zusätzliche Arbeit, aber die meisten, dass in einem Zyklus verarbeiten kann.

Wenn Sie fragen, für 32 Bit von 0x0001 Sie eine 2X Verstärkung zu bekommen. Der Prozessor von 0x0000 in das Ergebnisregister lesen und links 1 Byte verschieben, dann wieder gelesen von 0x0004 in ein temporäres Register, rechts 3 Bytes verschieben, dann OR es mit dem Ergebnisregister.

Bereich

Für jeden Adressraum gegeben, wenn die Architektur annehmen kann, dass die 2 LSBs sind immer 0 (zB 32-Bit-Maschinen), dann kann es 4-mal mehr Speicher zugreifen (die 2 gespeicherten Bits können vier verschiedene Zustände darstellen), oder die gleiche Menge an Speicher mit 2 Bits für so etwas wie Fahnen. Nimmt man die 2 LSBs aus einer Adresse, die Sie würde eine 4-Byte-Ausrichtung; auch als bezeichnet stride von 4 Bytes. Jedes Mal, wenn eine Adresse erhöht wird effektiv erhöht wird Bit 2, nicht das Bit 0, das heißt, die letzten 2 Bits immer weiter 00 werden.

Dies kann auch die physische Gestaltung des Systems beeinflussen. Wenn die Adresse Bus benötigt 2 weniger Bits, kann es zwei weniger Pins auf der CPU und 2 weniger Spuren auf der Leiterplatte.

Atomicity

Die CPU kann atomar auf ein ausgerichtetes Speicherwort arbeiten, was bedeutet, dass keine andere Anweisung, dass der Betrieb unterbrechen. Dies ist entscheidend für den korrekten Betrieb vieler Lock-freie Datenstrukturen und andere Gleichzeitigkeit Paradigmen.

Fazit

Das Speichersystem eines Prozessors ist ein bisschen komplexer und komplizierter als hier beschrieben; eine Diskussion über , wie eigentlich ein x86-Prozessor-Adressen-Speicher helfen können (viele Prozessoren arbeiten in ähnlicher Weise ).

Es gibt mnoch mehr Vorteile für die Speicherausrichtung zu haften, die Sie unter diesem IBM-Artikel lesen .

Der primäre Verwendung des Computers ist, Daten zu transformieren. Moderne Speicherarchitekturen und Technologien wurden über Jahrzehnte optimieren immer mehr Daten zu erleichtern, in, aus und zwischen mehr und schnelleren Ausführungseinheiten in eine höchst zuverlässigen Art und Weise.

Bonus: Caches

Eine weitere Ausrichtungs-for-Performance, die ich zuvor angedeutet, ist die Ausrichtung auf die Cache-Zeilen sind (beispielsweise auf einigen CPUs) 64B.

Für weitere Informationen darüber, wie viel Leistung kann durch den Einsatz von Caches gewonnen werden, werfen Sie einen Blick auf Galerie der Prozessor-Cache Effects ; aus dieser Frage auf Cache-Zeilengrößen

  

Verständnis von Cache-Zeilen kann für bestimmte Arten von Programmoptimierungen wichtig sein. Zum Beispiel kann die Ausrichtung der Daten bestimmen kann, ob eine Operation einer oder zwei Cache-Linien berührt. Wie wir im Beispiel oben gesehen haben, kann dies leicht in dem falsch ausgerichteten Fall bedeuten, dass wird der Betrieb zweimal langsamer sein.

Sie mit einigen Prozessoren ( die nehalem tun können dieser ), aber vorher Zugang zu allen Speichern auf einen 64-Bit (oder 32-Bit) Linie ausgerichtet wurde, weil der Bus 64 Bit breit ist, mußte man 64 Bit auf einmal holen, und es war wesentlich einfacher diese in ausgerichtetem 'chunks' von 64 Bits zu holen.

Wenn Sie also ein einziges Byte erhalten wollte, holte man den 64-Bit-Brocken und dann die Bits maskiert Sie nicht wollen. Einfach und schnell, wenn Ihr Byte war am rechten Ende, aber wenn es in der Mitte der 64-Bit-Brocken ist, würde man die unerwünschten Bits maskieren muß und dann die Daten über den richtigen Ort zu verschieben. Schlimmer noch, wenn Sie ein 2-Byte-Variable wollten, aber das war über zwei Stücke geteilt, dann die erforderlichen doppelten erforderliche Speicherzugriffe.

So, wie jeder denkt Speicher billig ist, machten sie nur der Compiler die Daten über den Prozessor des Chunk ausrichten Größen so läuft der Code schneller und effizienter auf Kosten verschwendet Speicher.

Im Grunde ist der Grund, weil der Speicherbus eine bestimmte Länge hat, die viel, viel kleiner als die Speichergröße ist.

So liest die CPU aus dem On-Chip-L1-Cache, die oft in diesen Tagen 32KB. Aber der Speicherbus, der den L1-Cache der CPU verbindet die erheblich geringere Breite der Cache-Zeilengröße haben. Dies wird in der Größenordnung von 128 Bits .

So:

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

Falsch ausgerichtete Zugriffe überlappen sich gelegentlich zwei Cache-Zeilen, und das wird eine ganz neue Cache, um die Daten zu erhalten, lesen Sie erfordern. Es könnte sogar verpassen ganzen Weg zu dem DRAM.

Darüber hinaus wird ein Teil der CPU haben auf den Kopf stellen, um gemeinsam ein einzelnes Objekt aus diesen beiden unterschiedlichen Cache-Zeilen, die jeweils ein Stück der Daten haben. Auf einer Linie, wird es in den sehr hohen Bits sein, in der anderen die sehr niedrigen Bits.

Es wird spezielle Hardware sein vollständig in die Rohrleitung integriert, die ausgerichtet sind Gegenstände auf die notwendigen Bits der CPU-Datenbus Griffe bewegen, aber eine solche Hardware kann für falsch ausgerichtete Objekte fehlen, weil es wahrscheinlich mehr Sinn macht, diese Transistoren für die Beschleunigung zu verwenden up-Programme richtig optimiert.

Auf jeden Fall lesen die zweite Speicher, dass manchmal notwendig ist, unabhängig von der Pipeline verlangsamen würde, wie viel Spezial-Hardware war (hypothetisch und dummerweise) gewidmet falsch ausgerichteten Speicheroperationen flicken.

@joshperry hat eine ausgezeichnete Antwort auf diese Frage gegeben. Neben seiner Antwort habe ich einige Zahlen, die grafisch die Effekte zeigen, die beschrieben wurden, insbesondere die 2X Verstärkung. Hier ist ein Link zu einem Google-Tabelle zeigt, was die Wirkung von unterschiedliche Wortzuordnungen aussehen. Darüber hinaus ist hier ein Link zu einem Github Kern mit dem Code für den Test. Der Testcode angepasst ist, von der Artikel von Jonathan Rentzsch geschrieben die @joshperry verwiesen. Die Tests wurden auf einem Macbook Pro mit einem Quad-Core 2,8 GHz Intel Core i7 64-Bit-Prozessor und 16 GB RAM.

Wenn ein System mit Byte-Speicher über einen 32-Bit breiten Speicherbus hat, bedeutet, dass es effektiv vier Byte breiten Speichersysteme, die alle verdrahtet sind zu lesen oder die gleiche Adresse zu schreiben. Eine ausgerichtete 32-Bit-Lese wird in allen vier Speichersystemen in den gleichen Adressinformationen gespeichert ist erforderlich, so dass alle Systeme können Daten gleichzeitig versorgen. Eine nicht ausgerichtete 32-Bit-Lese würde einige Speichersysteme benötigen Daten von einer Adresse zurückzukehren, und einige Daten aus der nächsthöheren Adresse zurückzukehren. Zwar gibt es einige Speichersysteme, die solche Anforderungen zu erfüllen, werden optimiert, um der Lage sein, (zusätzlich zu ihrer Adresse, haben sie effektiv ein „plus eins“ Signal, das ihnen eine Adresse um eins höher als angegeben verwenden verursacht) ein solches Feature erhebliche Kosten erhöht und die Komplexität auf ein Speichersystem; die meisten Rohstoff-Speichersysteme können einfach nicht zurückkehren Abschnitte unterschiedlicher 32-Bit-Wörter zugleich.

Wenn Sie ein 32-Bit-Datenbus haben, die Adresse Bus Adressleitungen mit dem Speicher verbunden werden von einem Start 2 , so dass nur 32-Bit-Adressen ausgerichtet in einem einzigen Buszyklus zugegriffen werden.

So, wenn ein Wort umspannt einen Adressenausrichtungsgrenze - dh A 0 16/32 für Bitdaten oder A 1 für 32-Bit-Daten nicht Null ist, zwei Buszyklen sind erforderlich, um die Daten zu erhalten.

Einige Architekturen / Befehlssätze nicht unaligned Zugriff unterstützen und eine Ausnahme auf solche Versuche erzeugen, so Compiler erzeugt nicht ausgerichteten Zugangscode erfordert nicht nur zusätzliche Buszyklen, aber zusätzliche Anweisungen, so dass es noch weniger effizient.

Auf PowerPC Sie eine ganze Zahl von einer ungeraden Adresse ohne Probleme laden kann.

Sparc und I86 und (glaube ich) Itatnium Hardware Ausnahmen auslösen, wenn Sie dies versuchen.

Ein 32-Bit-Last vs vier 8-Bit-Lasten gehen ist nicht viel Unterschied auf den meisten modernen Prozessoren zu machen. Ob die Daten bereits im Cache sind oder nicht, wird eine weit größere Wirkung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top