2011-06-20 6 views

Odpowiedz

10

Zasadniczo, jeśli trzeba trudniejsze wyrównanie niż malloc da ty. Malloc zasadniczo zwraca wskaźnik wyrównany w taki sposób, że może być używany z dowolnym typem pierwotnym (często 8 bajtów na zwykłych komputerach stacjonarnych).

Czasami jednak wymagana jest pamięć wyrównana do innych granic, na przykład wyrównana do 4K, itd. W takim przypadku potrzebowałbyś memalign.

Będziesz potrzebować tego, na przykład,

  • pisząc menedżera pamięci (takich jak garbage collector). W takim przypadku czasami przydaje się praca z pamięcią wyrównaną przy większych rozmiarach bloków. W ten sposób można przechowywać metadane wspólne dla wszystkich obiektów w danym bloku na dole przydzielonego obszaru i uzyskać do niego dostęp poprzez maskowanie najmniej znaczących bitów wskaźnika obiektu.
  • podczas łączenia ze sprzętem (nigdy nie robiłem tego sam, ale IIRC, niektóre rodzaje urządzeń blokowych wymagają wyrównania pamięci). Zobacz odpowiedź n.m. w celu uzyskania szczegółowych informacji.
+0

@ Dirk, wydaje się, że to nie odpowiada ** kiedy ** potrzebujemy. –

+2

Więcej przykładów: Typy SIMD mogą wymagać większego wyrównania, niż oferuje 'malloc'. Kod grający bardzo wymyślne sztuczki dla wydajności może wymagać wyrównania odpowiadającego rozmiarowi linii pamięci podręcznej - jest to prawdopodobnie najczęstsze, jeśli piszesz dynamiczny linker (np. Kod ładujący pliki wykonywalne do pamięci), kod, który ładujesz, może chcieć jego funkcje dostosowane do granic linii pamięci podręcznej. –

+0

@Steve Jessop, czy skorzystamy z rozmiaru pamięci '16 * 1024' i wyrównanego do' 16' zamiast domyślnego '8'? –

2

Różne urządzenia mogą wymagać wyrównania, które nie mogą spełnić malloc. Strona podręcznika systemu Linux podaje jeden taki przykład, cytuję:

W wielu systemach istnieją ograniczenia dotyczące ograniczeń, np. , np. na buforach używanych do wejścia/wyjścia urządzenia z blokiem bezpośrednim. POSIX określa pathconf (ścieżka, _PC_REC_XFER_ALIGN) wywołanie , które mówi, jakie wyrównanie jest potrzebne.

1

Kilka zastosowań:

  • Niektóre procesory mają instrukcji, które działają tylko na danych, które jest dostosowana do potęgi dwójki większej lub równej wielkości bufora - na przykład bit odwrotnej adresowania instrukcje używane w ffts (szybkie transformaty Fouriera).

  • Wyrównywanie danych do granic pamięci podręcznej w celu optymalizacji dostępu w aplikacjach wieloprocesorowych, dzięki czemu dane z tej samej linii pamięci podręcznej nie są dostępne dla dwóch procesorów jednocześnie.

Zasadniczo, jeśli nie trzeba robić absurdalnych poziomów optymalizacji i/lub sprzętu nie wymaga, że ​​tablica będzie na danej granicy wtedy można zapomnieć o posix_memalign.

+0

co masz na myśli przez 'granice pamięci podręcznej' i' linię pamięci podręcznej'? –

+0

@ kompilator-fan: http://en.wikipedia.org/wiki/CPU_cache –

4

Jedyne zalety posix_memalign, o ile mogę powiedzieć, to:

  1. Przydzielanie strona wyrównany (zazwyczaj 4096 lub większe wyrównanie) Pamięć dla celów specyficzne dla sprzętu.
  2. Złe hacki, w których zatrzymujesz niskie wartości N bitów wskaźnika zero, dzięki czemu możesz przechowywać N -bitową liczbę całkowitą w najniższych bitach. :-)
+0

Nie rozumiem drugiego punktu, czy możesz podać przykład? –

+1

@ Kompiluj-fan, jeśli wskazane obiekty są większe niż, powiedzmy, 4-bajty i wyrównane na granicach 4-bajtowych, możesz wykraść 2 bity od dołu wskaźnika, jeśli zawsze zamaskujesz je na zero przed użyciem wskaźnika jako wskaźnika. –

+0

dokładny powód, dla którego o to pytam, jest taki, ponieważ widzę, że nginx robi to, 'ngx_memalign (NGX_POOL_ALIGNMENT, rozmiar, log);' tutaj 'NGX_POOL_ALIGNMENT' jest zdefiniowany jako' 16', http: //nginxs.googlecode.com/svn- historia/trunk/src/core/ngx_palloc.c –