Wyrównanie linii pamięci podręcznej i znajomość rozmiaru linii pamięci podręcznej


Aby zapobiec fałszywemu udostępnianiu, chcę wyrównać każdy element tablicy z wierszem pamięci podręcznej. Więc najpierw muszę znać rozmiar linii pamięci podręcznej, więc przypisuję każdemu elementowi tę liczbę bajtów. Po drugie, chcę, aby początek tablicy był wyrównany do linii pamięci podręcznej.
Używam platformy Linux i 8-rdzeniowego procesora x86. Po pierwsze, jak znaleźć rozmiar linii pamięci podręcznej. Po drugie, jak ustawić linię pamięci podręcznej w C. Używam kompilatora gcc.
W ten sposób struktura byłaby następująca, na przykład przy założeniu rozmiaru linii pamięci podręcznej równego 64.
element[0] occupies bytes 0-63
element[1] occupies bytes 64-127
element[2] occupies bytes 128-191

i tak dalej, zakładając oczywiście, że 0-63 jest wyrównane do linii pamięci podręcznej.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Używam platformy Linux i 8-rdzeniowego procesora x86. Po pierwsze, jak znaleźć rozmiar linii pamięci podręcznej.

$ getconf LEVEL1_DCACHE_LINESIZE
64

Przekaż wartość jako definicję makra do kompilatora.
$ gcc -DLEVEL1_DCACHE_LINESIZE=`getconf LEVEL1_DCACHE_LINESIZE` ...

W czasie wykonywania
sysconf (_SC_LEVEL1_DCACHE_LINESIZE)
może być użyty do uzyskania rozmiaru pamięci podręcznej L1.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Aby znaleźć wymiary, musisz to sprawdzić, korzystając z dokumentacji procesora, afaik, nie ma na to programowego sposobu. Z drugiej strony jednak większość linii pamięci podręcznej ma standardowy rozmiar oparty na standardach Intels. Na x86 linie pamięci podręcznej mają 64 bajty, jednak aby zapobiec fałszywemu udostępnianiu, musisz postępować zgodnie z zaleceniami procesora, na który celujesz (firma Intel ma specjalne uwagi na temat swoich procesorów opartych na netburst), generalnie musisz wyrównać do 64 bajtów w tym celu (Intel twierdzi, że należy również unikać przekraczania granic 16-bajtowych).
To w C lub C ++ wymaga użycia funkcji standardowej
aligned_alloc
lub jednego ze specjalnych specyfikatorów kompilatora, takich jak
__attribute __ ((align (64)))
lub
__declspec (align (64))
. Aby podzielić elementy struktury na różne linie pamięci podręcznej, element musi zostać wstawiony na tyle duży, aby wyrównać z następnymi 64-bajtowymi granicami
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Innym prostym sposobem jest po prostu feline/proc/cpuinfo:
cat/proc/cpuinfo | cache_alignment grep
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Nie ma całkowicie przenośnego sposobu uzyskania rozmiaru pamięci podręcznej. Ale jeśli korzystasz z x86/64, możesz wywołać instrukcję
cpuid
, aby uzyskać wszystko, co musisz wiedzieć o pamięci podręcznej, w tym rozmiar, rozmiar linii pamięci podręcznej, liczbę poziomów itp.
http://softpixel.com/~cwright/ ... d.php
http://softpixel.com/~cwright/ ... d.php
(Przewiń trochę w dół, strona jest o SIMD, ale ma sekcję pobierającą cacheline.)
Jeśli chodzi o wyrównywanie struktur danych, nie ma również całkowicie przenośnego sposobu, aby to zrobić. GCC i VS10 mają różne sposoby ustawiania wyrównania struktury.
Jednym ze sposobów „zhakowania” jest wypełnienie struktury nieużywanymi zmiennymi, dopóki nie będzie pasować do żądanego wyrównania.
Aby wyrównać mallocs (), wszystkie główne kompilatory również mają dostosowane funkcje malloc do tego celu.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

posix_memalign
http://linux.die.net/man/3/posix_memalign

lub

valloc

można użyć do wyrównania przydzielonej pamięci z linią pamięci podręcznej.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jeśli ktoś zastanawia się, jak łatwo jest to zrobić w C ++, zbudowałem bibliotekę z klasą
CacheAligned & < T & >
, która obsługuje rozmiar linii pamięci podręcznej, a także wyrównanie dla odwołanie do
T <!-- code object--> zostało wywołane przez wywołanie funkcji[code].Ref ()
dla obiektu
CacheAligned & < T & >
. Możesz również użyć
Aligned & < typename T, size_t Alignment & >
, jeśli znasz rozmiar linii pamięci podręcznej z wyprzedzeniem lub po prostu chcesz trzymać się bardzo powszechnych 64 (bajtów). [/code] https://github.com/NickStrupat/Aligned
https://github.com/NickStrupat/Aligned
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Oto stół
http://cache-line-sizes.surge.sh/
co zrobiłem, na którym jest większość procesorów Arm/Intel. Możesz go użyć jako odniesienia podczas definiowania stałych, więc nie musisz generalizować rozmiaru linii pamięci podręcznej we wszystkich architekturach.
Miejmy nadzieję, że niedługo zobaczymy w przypadku C ++

rozmiar interfejsu sprzętowego
https://en.cppreference.com/w/ ... _size
co powinno być dokładnym sposobem uzyskania tych informacji (zakładając, że powiesz kompilatorowi swoją docelową architekturę).

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się