Grundsätzlich, wenn Sie eine härtere Ausrichtung benötigen, als Malloc Ihnen geben wird. Malloc gibt im Allgemeinen einen Zeiger zurück, der so ausgerichtet ist, dass er mit jedem der primitiven Typen verwendet werden kann (häufig 8 Bytes auf gewöhnlichen Desktop-Rechnern).
Manchmal benötigen Sie jedoch Speicher, der an anderen Grenzen ausgerichtet ist, z. B. 4K-ausgerichtet usw. In diesem Fall benötigen Sie memalign.
Das bräuchten Sie z.
beim Schreiben eines Speichermanagers (z. B. eines Garbage Collectors). In diesem Fall ist es manchmal praktisch, mit Speicher zu arbeiten, der auf größere Blockgrößen ausgerichtet ist. Auf diese Weise können Sie Metadaten speichern, die allen Objekten in einem bestimmten Block am Ende des zugewiesenen Bereichs gemeinsam sind, und darauf zugreifen, indem Sie einfach die niederwertigsten Bits des Objektzeigers maskieren.
bei der Verbindung mit Hardware (ich habe das nie selbst gemacht, aber IIRC, bestimmte Arten von Blockgeräten erfordern ausgerichteten Speicher). Einzelheiten finden Sie in der Antwort von nm.
@Dirk, scheint das nicht zu beantworten Wenn wir brauchen.
– Compiler-Fan
20. Juni 2011 um 11:53 Uhr
Weitere Beispiele: SIMD-Typen benötigen möglicherweise mehr Ausrichtung als malloc bietet. Code, der sehr ausgefallene Tricks für die Leistung spielt, möchte möglicherweise eine Ausrichtung, die der Cache-Zeilengröße entspricht – dies ist vielleicht am häufigsten, wenn Sie einen dynamischen Linker schreiben (dh Code zum Laden von ausführbaren Dateien in den Speicher), den Code, den Sie laden möchten seine Funktionen sind auf Cache-Line-Grenzen ausgerichtet.
– Steve Jessop
20. Juni 2011 um 12:08 Uhr
@Steve Jessop, werden wir davon profitieren, wenn die Speichergröße von 16*1024 und ausgerichtet durch 16 statt der Vorgabe 8?
– Compiler-Fan
20. Juni 2011 um 12:19 Uhr
@Steve: §7.20.3 „Der bei erfolgreicher Zuweisung zurückgegebene Zeiger ist passend ausgerichtet, sodass er einem Zeiger auf zugewiesen werden kann jede Art von Objekt und dann verwendet, um auf ein solches Objekt zuzugreifen …” (Hervorhebung hinzugefügt). In der Praxis bedeutet dies, dass auf modernen 64-Bit-Systemen mit 128-Bit-SIMD-Einheiten malloc gibt Speicher zurück, der an 16-Byte-Grenzen ausgerichtet ist, obwohl Zeiger nur 8 (oder 4) Bytes breit sind.
– Dietrich Ep
20. Juni 2011 um 12:24 Uhr
@Dietrich: Das könnte es bedeuten, aber es ist nicht das, was Implementierungen tatsächlich tun. Sie können damit leben oder sowohl MSVC als auch GCC für nicht konform erklären und sich weigern, für sie zu schreiben. In diesem Fall benötigen Sie wahrscheinlich eine andere Art von Arbeit als die C-Programmierung 😉 Soweit mir bekannt ist, lautet die Fluchtbegründung, dass die Implementierung Code “brechen” darf, da SIMD-Typen Erweiterungen des Standards sind das sie verwendet, indem es diese zusätzliche Anforderung einführt, dass der Speicher superausgerichtet ist.
– Steve Jessop
20. Juni 2011 um 12:30 Uhr
Die einzigen Vorteile von posix_memalignsind, soweit ich das beurteilen kann:
Zuweisen von seitenausgerichtetem Speicher (normalerweise 4096 oder größere Ausrichtung) für hardwarespezifische Zwecke.
Böse Hacks, bei denen du das Tief hältst N Bits eines Zeigers Null, damit Sie an speichern können N-bit Ganzzahl in den niedrigen Bits. 🙂
@compile-fan, wenn die Objekte, auf die Sie zeigen, alle größer als beispielsweise 4 Bytes sind und an 4-Byte-Grenzen ausgerichtet sind, können Sie 2 Bits vom unteren Rand des Zeigers stehlen, wenn Sie sie immer auf Null maskieren bevor Sie den Zeiger als Zeiger verwenden.
Es hört sich so an, als würde nginx seine eigenen Speicherpools verwalten und im Grunde replizieren malloc zusätzlich zu seinen eigenen zugewiesenen Blöcken, und möchte sicher sein, dass es bis zu 16 Byte Ausrichtung bereitstellen kann. Ich bin mir nicht sicher, warum es sich seitdem darum kümmert malloc bietet bereits eine ausreichende Ausrichtung für alle C-Typen, und wenn Sie einen Block erhalten, erhalten Sie ihn malloc und beim Aufschneiden keine nicht ausgerichteten Offsets angewendet, bliebe es ausgerichtet. Nach der letzten Reihe von Fragen zu nginx zu urteilen, bezweifle ich, ob die Autoren von nginx verstanden haben, warum sie es verwenden memalign an erster Stelle…
– R.. GitHub HÖR AUF, EIS ZU HELFEN
22. Juni 2011 um 15:57 Uhr
Verschiedene Hardware kann Ausrichtungsanforderungen haben, die malloc kann nicht befriedigen. Die Linux-Manpage gibt ein solches Beispiel, ich zitiere:
Auf vielen Systemen gibt es Ausrichtungseinschränkungen, z. B. bei Puffern, die für direkte Blockgeräte-E/A verwendet werden. POSIX gibt den pathconf(path,_PC_REC_XFER_ALIGN)-Aufruf an, der angibt, welche Ausrichtung erforderlich ist.
Ein paar Verwendungen:
Einige Prozessoren haben Anweisungen, die nur mit Daten arbeiten, die auf eine Zweierpotenz größer oder gleich der Puffergröße ausgerichtet sind – zum Beispiel Anweisungen zur bitumgekehrten Adressierung, die in ffts (schnelle Fourier-Transformationen) verwendet werden.
Zum Ausrichten von Daten an Cache-Grenzen zum Optimieren des Zugriffs in Multiprocessing-Anwendungen, sodass nicht von zwei Prozessoren gleichzeitig auf Daten in derselben Cache-Zeile zugegriffen wird.
Wenn Sie keine absurden Optimierungen durchführen müssen und/oder Ihre Hardware nicht verlangt, dass sich ein Array auf einer bestimmten Grenze befindet, können Sie posix_memalign im Grunde vergessen.
13351600cookie-checkWann müssen wir posix_memalign anstelle von malloc verwenden?yes
Wir sollten das offizielle Dokument besser wie folgt lesen: man7.org/linux/man-pages/man3/posix_memalign.3.html
– Jamischon
12. August um 6:01 Uhr