Korzystając z nowych narzędzi do wyrównania C++ 11, chciałem się upewnić, że zestaw zmiennych tymczasowych (stosowych) będzie znajdować się w jednej linii pamięci podręcznej. Moja pierwsza naiwna próba była następująca:Zmienne stosy wyrównane do pamięci podręcznej
int main() {
alignas(64) int a; // 0x7fffc58aac80, properly aligned at 64
int b; // 0x7fffc58aac7c
int c; // 0x7fffc58aac78
return 0;
}
Głupi mnie! Stack nie przypisuje zmiennych w ten sposób, dlatego a
będzie znajdować się na innej linii pamięci podręcznej niż b
i c
.
Czy to oznacza, że Jedynym sposobem prawidłowego wyrównania wielu zmiennych jest agregacja?
struct alignas(64) Abc {
int x;
int y;
int z;
};
int main() {
Abc foo;
// x 0x7fff40c2d3c0 (aligned at 64)
// y 0x7fff40c2d3c4
// z 0x7fff40c2d3c8
return 0;
}
Compiler: Clang 3.2
Czy naprawdę sądzisz, że posiadanie wszystkich tych zmiennych w tej samej linii pamięci podręcznej poprawi wydajność? Szanse są całkiem dobre, że stos znajduje się w pamięci podręcznej. –
To * może * mieć wpływ, jeśli zmienne te muszą być współużytkowane przez wiele rdzeni, tak aby dowolny rdzeń chciał do nich pisać, musi używać wszystkich trzech zmiennych jednocześnie. Jeśli wszystkie znajdują się w tej samej linii pamięci podręcznej, a dostęp do tych zmiennych jest rzadkością, ruch spójności zmniejszyłby się. Nie ma jednak gwarancji, że linia może zostać unieważniona między odczytaniem dwóch zmiennych w tym samym wierszu. –
Współczesne kompilacje nie przechowują zmiennych na stosie w stałej lokalizacji (oczywiście, jeśli nie weźmiesz ich adresu). Więc jeśli 'a' i' b' współużytkują linię pamięci podręcznej, po napisaniu do którejkolwiek z tych, które mogą się zmienić. (Jest to typowe dla statycznej optymalizacji pojedynczego przypisania) – MSalters