Wann müssen wir posix_memalign anstelle von malloc verwenden?

Lesezeit: 5 Minuten

Benutzer-Avatar
Compiler-Fan

Scheint posix_memalign Lassen Sie eine angepasste auswählen alignment,aber wann ist das nötig?

malloc hat die Ausrichtungsarbeiten bereits intern durchgeführt.

AKTUALISIEREN

Der genaue Grund, warum ich das frage, ist, weil ich sehe, dass nginx dies tut,ngx_memalign(NGX_POOL_ALIGNMENT, size, log);,hier NGX_POOL_ALIGNMENT ist definiert als 16, nginxs.googlecode.com/svn-history/trunk/src/core/ngx_palloc.c

Benutzer-Avatar
Dolch

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:

  1. Zuweisen von seitenausgerichtetem Speicher (normalerweise 4096 oder größere Ausrichtung) für hardwarespezifische Zwecke.
  2. 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.

    – Luser Drog

    21. Juni 2011 um 3:15 Uhr

  • Der genaue Grund, warum ich das frage, ist, weil ich sehe, dass Nginx dies tut,ngx_memalign(NGX_POOL_ALIGNMENT, size, log);,hier NGX_POOL_ALIGNMENT ist definiert als 16,nginxs.googlecode.com/svn-history/trunk/src/core/ngx_palloc.c

    – Compiler-Fan

    21. Juni 2011 um 11:40 Uhr

  • 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.

1335160cookie-checkWann müssen wir posix_memalign anstelle von malloc verwenden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy