2015-07-06 22 views
5

Tak więc czytałem, że gdy zmienne są zadeklarowane w języku C++, jeśli chcesz uzyskać optymalną pamięć podręczną, pamięć powinna pozostać przy naturalnym wyrównaniu. Przykład:Wyrównanie pamięci w języku C++

int a; // memory address should end in 0x0,0x4,0x8,0xC 
int b[2]; // 8 bytes 0x0,0x8 
int b[4]; // 16 bytes 0x0 

Jednak w praktyce zmienne te nie stosują się do zasad „naturalne wyrównanie”, zmienna 16 bajt przebywał na adres pamięci, który zakończył się w 0xC. Dlaczego to ?

+3

Tablice nie są objęte wyrównania, tylko poszczególne elementy są – Quentin

+0

chcieć miejscu dokładna przypadku –

+0

Nie ma sprawa naprawdę im po prostu eksperymentować, wszystko udało mi się znaleźć to, że niezależnie od zmiennej wielkości wszystko zawsze było 4 wyrównane bajtowo, chyba że był to 1-bajtowy typ danych. Po prostu ciekawy dlaczego. – Student123

Odpowiedz

4

Naturalne wyrównanie pamięci ogólnie odnosi się do wyrównania poszczególnych zmiennych, a nie do tablic zmiennych. Zatem tablica 4-bajtowych liczb całkowitych (jak najwyraźniej powyżej) jest naturalnie wyrównana do granicy 4-bajtowej, a nie do 16-bajtowej granicy.

Naturalne wyrównanie pamięci zwykle odnosi się do sposobu projektowania i implementacji instrukcji ładowania/składowania procesora, a nie rozmiaru linii pamięci podręcznej. Procesor nie ładuje całych tablic jednocześnie (z wyjątkiem obciążeń wektorowych). Tak więc procesor nie dba o to, czy liczba całkowita, którą ładuje, jest częścią tablicy, czy też nie.

Obciążenia wektorowe, które ładują małe tablice w tym samym czasie, często mają bardziej rygorystyczne wymagania wyrównania. Na przykład, aby wykonać wyrównane obciążenie wektorowe na x86, element musi zostać wyrównany do 16 bajtów.

+0

Próbuję również 16-bajtowych typów danych, które nadal nie zostały wyrównane do 0x0. Wszystko, co mogę powiedzieć, to to, że wszystko jest wyrównane do 4 bajtów niezależnie od rozmiaru. Czy niektóre kompilatory robią to inaczej lub w różnych procesorach? – Student123

1

Nie ma gwarancji, dostosowania

+0

Powinien być komentarzem. – scohe001

+1

@LegalizeIt to jest pełna odpowiedź, OP twierdził, że wyrównanie powinno być coś, oświadczyłem, że nie ma guarentee. Reszta odpowiedzi została podana w pierwszym komentarzu. W int może mieć adres, który jest dziwny, prawdopodobnie nie będzie, ale może. –

+0

@ scohe001 jego odpowiedź –

2

C++ nie będzie wyrównać coś na linii pamięci podręcznej, ponieważ dla wszystkich zamiarów i celów, że nie wiedzą, że nie jest cache.

Jeśli chcesz coś wyrównać na granicy 16-bitowej spróbuj posix_memalign() dla rzeczy na stercie lub (jeśli używasz GCC) na stosie, int x __attribute__ ((aligned (16))). W C++ 11 jest alignas specifier.

Nie wiem, jak zadzwonić pod numer new() z gwarantowanym wyrównaniem.

+0

Możesz napisać własną 'operator new()' i wymusić wyrównanie –

+0

Mam rację mówiąc, że w miarę jak fragment pamięci jest wyrównany do 4 bajtów, procesor zawsze będzie wykorzystywał większość danych i będzie nie trzeba robić więcej niż jeden odczyt, aby uzyskać dowolną zmienną 4-bajtową? – Student123

+0

@ Student123 Myślę, że to będzie zależeć od procesora. Powiedziałbym, że ogólnie jest to dobra zasada do naśladowania. Wiem, że nowoczesne mikroarchitektury x86 nie penalizują już nieprzypisanych ładunków. – hayesti

0

Według Intel® 64 i IA-32 Architectures optymalizacji Instrukcja obsługi (sekcja pomaga B.4.5.2)

32 bajtów instrukcji, które obejmują AVX przechowywania dwóch stron wymagają wspomagania go kosztuje około 150 cykle.