2010-09-29 18 views

Odpowiedz

28

Absolutnie. C++ gwarantuje, że kolejność obiektów w pamięci jest taka sama jak kolejność deklaracji, chyba że interweniuje kwalifikator dostępu.

Obiekty, które są bezpośrednio przylegające, z większym prawdopodobieństwem znajdują się na tej samej linii pamięci podręcznej, więc jeden dostęp do pamięci pobierze je oba (lub wypłucze obie z pamięci podręcznej). Efektywność pamięci podręcznej może również ulec poprawie, ponieważ odsetek użytecznych danych w niej może być wyższy. Mówiąc krótko, położenie przestrzenne w kodzie przekłada się na położenie przestrzenne w celu uzyskania wydajności.

Ponadto, jak zauważa Jerry w komentarzach, kolejność może wpływać na ilość wypełnienia. Posortuj elementy, zmniejszając rozmiar, co jest również zmniejszeniem wyrównania (zwykle traktuj tablicę jako tylko jeden element jej typu i element członkowski struct jako najbardziej wyrównany element). Niepotrzebne wypełnienie może zwiększyć całkowity rozmiar struktury, prowadząc do większego ruchu pamięci.

C++ 03 §9/12:

Nonstatic członkowie danych o (spoza Unii) klasy zadeklarowane bez interwencyjnym access-specyfikatorem przydzielane są tak, że później członkowie mają wyższe adresy wewnątrz obiekt klasy . Kolejność przydzielania niestatycznych elementów danych oddzielonych przez specyfikator dostępu jest nieokreślona (11.1). Wyrównanie implementacji wymagania mogą spowodować, że dwaj sąsiadujący członkowie nie będą przydzielani od razu do siebie po ; więc może wymagać przestrzeni do zarządzania funkcji wirtualnych (10.3) i wirtualnych klas bazowych (10.1).

+2

Wow, nie zdawałem sobie z tego sprawy, ale wysłałem tę odpowiedź 112 * sekund * po wysłaniu pytania! – Potatoswatter

+0

@Potatoswatter_cool achievement !!! – Pooria

+0

Również jego rozmiar może mieć znaczenie. Ponieważ procesor x86 (i prawdopodobnie wiele innych) ma specjalne kody operacji dostępu do pamięci z rejestrem indeksu, dostęp do tablicy obiektów o rozmiarach 1, 2, 4 lub 8 bajtów będzie uzyskiwany szybciej. – ruslik

7

Absolutnie zgadzam się z Potatoswatter. Jednak należy dodać jeszcze jeden punkt dotyczący linii pamięci podręcznej procesora.

Jeśli twoja aplikacja jest wielowątkowa i inne wątki odczytują/zapisują członków twojej struktury - bardzo ważne jest, aby upewnić się, że ci członkowie są , a nie w obrębie tej samej linii pamięci podręcznej.

Chodzi o to, że ilekroć wątek modyfikuje adres pamięci, który jest buforowany w innym CPU - CPU natychmiast unieważnia linię pamięci podręcznej zawierającą ten adres. Tak więc niewłaściwa kolejność członków może prowadzić do nieuzasadnionego unieważniania pamięci podręcznej i obniżenia wydajności.

4

Oprócz wykonywania wykonawczego, opisane w cache-linia związanych odpowiedzi, myślę, że należy również rozważyć wydajność pamięci, to jest rozmiar obiektu klasy.

Ze względu na padding rozmiar obiektu klasy zależy od kolejności deklaracji zmiennej składowej.

Poniższa deklaracja będzie prawdopodobnie zajmie 12 bajtów

class foo { 
    char c1; 
    int i; 
    char c2; 
} 

Jednak po prostym ponownego uporządkowania kolejności deklaracji zarejestrował następujące prawdopodobnie wziąć 8 bajtów

class bar { 
    int i; 
    char c1; 
    char c2; 
} 

W maszynach ustawionych z 4-bajtowymi słowami:

sizeof(foo) = 12 

ale

sizeof(bar) = 8 
Powiązane problemy