Czołem. Bawię się z grubsza tym, co napisane jest w tym artykule: http://igoro.com/archive/gallery-of-processor-cache-effects/
Mamy tam taki "akapit" : Example 3: L1 and L2 cache sizes.
Badany jest tutaj wpływ pamięci podręcznej na wydajność.
Napisałem taki kod (kalka tego co w przykładzie)
var kilobajt= 1024 * 1024 / 8; // dzielę przez 8, bo long ma 8 bajtów
long steps = kilobajt / 16 * "cokolwiek";//liczba iteracji. Najlepiej wstawić taką liczbę, żeby każda iteracja kończyła się na "końcu" tablicy.
long [] tab= new long[kilobajt];
long tabLength = tab.Length - 1;
for (long i = 0; i < steps; i++)
{
tab[(i * 16) % tabLength]++;
}
W zależności od rozmiaru tablicy, ten kod ma wykonywać przez różną ilość czasu. Wpływ na czas trwania obliczeń ma pamięć podręczna (jej wielkość i liczba poziomów).
mój proc to intel i3 4160.
Pamięć podręczna L1
2 x 32 KB (Dane)
2 x 32 KB (Instrukcje)
Pamięć podręczna L2
2 x 256 KB
Pamięć podręczna L3
3 MB
Czas trwania (w milisekundach) dla różnych wielkości tablicy (oczywiście przy tej samej liczbie iteracji) to:
arraySize = 1 KB, time = 1185
arraySize = 2 KB, time = 1282
arraySize = 4 KB, time = 1642
arraySize = 8 KB, time = 1825
arraySize = 16 KB, time = 1868
arraySize = 32 KB, time = 1892
arraySize = 64 KB, time = 1860
arraySize = 128 KB, time = 1950
arraySize = 256 KB, time = 1933
arraySize = 512 KB, time = 1953
arraySize = 1024 KB, time = 2071
arraySize = 2048 KB, time = 2435
arraySize = 4096 KB, time = 3303
Widać, że od 8KB do 1024KB czas trwania wynosi 1.8-2.1 sekundy. Poniżej tej wartości, czas jest mniejszy. Powyżej czas rośnie (niestety, w .NET chyba nie mogę zrobić ciągłej tablicy o większej elementów niż wartość 32 bitowego inta, więc nie zbadałem dla większych tablic).
Ok, ale jak to się ma do mojego procesora ? Niby mam 3MB L3, ale już od 2MB widać większy czas (czyli cała tablica 2MB nie zmieściła się w L3, które ma 3MB).
mam 256KB L2 na rdzeń, ale nie widze jakiegoś "skoku" w tym punkcie. Czas obliczeń dla tablic o rozmiarach: 32KB, 64KB, 128KB, 256KB, 512KB, 1024 KB jest zbliżony.
Sprawdzałem też dla int (zamiast long). Wtedy również czasy "rosną" od 2MB
arraySize = 512 KB time = 2568
arraySize = 1024 KB, arraySize = 1 MB time = 2613
arraySize = 2048 KB, arraySize = 2 MB time = 3149
arraySize = 4096 KB, arraySize = 4 MB time = 4926
Czemu mam takie, a nie inne wyniki ?