otwarty
Zamknąć

Za co odpowiada pamięć podręczna w procesorze? Nowe podejście do buforowania procesora. Jaka jest głośność i na co wpływa?

Pamięć podręczna procesora- specjalna pamięć wewnątrz procesora przyspieszająca dostęp do pamięci RAM. Czasami pamięć podręczna procesora nazywana jest pamięcią główną, ponieważ można uzyskać do niej dostęp w bardzo krótkim czasie. Zazwyczaj pamięć podręczna w procesorach oparta jest na klasycznych przerzutnikach – tzw. pamięci statycznej (SRAM). Na przykład pamięć RAM zbudowana jest na kondensatorach, które są od czasu do czasu ładowane. Wyzwalacze zapewniają niemal natychmiastowy dostęp do siebie, mają jednak dwie główne wady:

  • stosunkowo wysoki koszt produkcji
  • stałe zużycie energii
  • To właśnie te ograniczenia pamięci SRAM nie pozwalają na tworzenie na niej pamięci RAM.

    Poziomy pamięci podręcznej procesora

    W nowoczesnych procesorach pamięć podręczna jest podzielona na kilka poziomów

    Algorytm pamięci podręcznej

    Algorytmem działania pamięci podręcznej steruje specjalny kontroler umieszczony w procesorze. Może dynamicznie zmieniać swój sposób działania, w zależności od okoliczności. Ale ogólny algorytm pamięci podręcznej to:

    Kiedy procesor wysyła żądanie odczytu, kontroler pamięci podręcznej szuka wartości w pamięci podręcznej i jeśli ją znajdzie, wysyła ją do procesora. Jeśli wartość nie zostanie znaleziona, kontroler wysyła żądanie dalej: albo do pamięci podręcznej niższego poziomu, albo do pamięci RAM. Po odczytaniu wartości z niższego poziomu pamięć podręczna dodaje tę wartość do siebie i przy następnym dostępie od razu przekazuje ją procesorowi.

    Gdy procesor wysyła żądanie zapisu do pamięci RAM, następuje to kontroler pamięci podręcznej aktualizuje wartość dla siebie i przekazuje ją do niższych poziomów. Ostatecznie wartość trafia do pamięci RAM. Pamięć podręczna zapisu zwykle działa przy użyciu tego algorytmu. Możesz oczywiście zapisać wartość tylko w pamięci podręcznej, ale wtedy inne komponenty (na przykład DMA - bezpośredni dostęp do pamięci) wiążą się z ryzykiem uzyskania nieaktualnej wartości podczas dostępu do pamięci RAM.

    Częstotliwość pamięci podręcznej

    Ponieważ pamięć SRAM może pracować z bardzo wysokimi częstotliwościami, pamięć podręczna procesora zwykle pracuje z tą samą częstotliwością, co sam procesor. Zwiększa to dodatkowo szybkość pracy z tego typu pamięciami.

    Inteligentna pamięć podręczna

    Nowoczesne kontrolery pamięci podręcznej potrafią odgadnąć, do których komórek pamięci procesor wkrótce uzyska dostęp, i z wyprzedzeniem załadować je do pamięci podręcznej. Na przykład, jeśli procesor uzyskał dostęp do komórki 42, a następnie 43, to istnieje duże prawdopodobieństwo, że trzeci dostęp będzie dotyczył komórki 44. Dlatego kontroler wcześniej ładuje wartość komórki 44 do swojej ultraszybkiej pamięci.

    Pierwsza skrytka

    W procesorze 8086 znajdowało się coś w rodzaju pamięci podręcznej. Miał on 6-bajtową pamięć podręczną instrukcji. Niewielka liczba, bez wielkich zdolności intelektualnych, ale znacznie zwiększyła wydajność systemu. Ale w przypadku procesora 80386 zaczęto używać prawdziwej pamięci podręcznej. W tamtych czasach dostęp do pamięci RAM wymagał 120 ns czasu. Ale obok procesora zainstalowałem specjalny układ pamięci podręcznej a dostęp do niej był 12 razy szybszy niż do pamięci RAM. Jednak ta pamięć (SRAM) była dość droga i zainstalowanie dużego układu pamięci podręcznej było nieopłacalne. Dlatego pamięć podręczna pierwszego procesora została ograniczona do 64 kilobajtów i została zainstalowana osobno. Począwszy od procesora 80486 Pamięć podręczna procesora zaczął żyć zgodnie ze swoją nazwą, ponieważ został zainstalowany bezpośrednio w procesorze.

    Miejsce instalacji pamięci podręcznej

    Jak wspomniano powyżej, procesor 80386 nie miał wewnętrznej pamięci podręcznej. Pamięć podręczna została zainstalowana jako oddzielny układ na płycie głównej. W komputerach opartych na procesorze 80486, tak jak poprzednio, pamięć podręczna znajdowała się na płycie głównej, ale był to drugi poziom. Ustawiono pierwszy poziom pamięci podręcznej bezpośrednio w procesorze. Z biegiem czasu i rozwoju technologii produkcji chipów pamięć podręczna procesora została całkowicie przeniesiona do procesora, a także kontrolera pamięci RAM.

    Pamięć podręczna procesora to skuteczny sposób na zwiększenie wydajności procesora poprzez zwiększenie szybkość pracy z pamięcią RAM.

    Pierwszym procesorem wyposażonym w pamięć podręczną L2 był Pentium Pro z 1995 roku. Miał 256 lub 512 KB wbudowanej pamięci podręcznej L2, co dawało mu znaczną przewagę nad konwencjonalnymi procesorami Pentium, których pamięć podręczna znajdowała się na płycie głównej. Wraz z pojawieniem się Pentium II dedykowana pamięć podręczna „zadomowiła się” obok procesora w module Slot 1. Jednak dopiero Pentium III drugiej generacji dla Socket 370 przeniosło pamięć podręczną na chip procesora. Trwa to do dziś, ale są procesory z małą ilością pamięci podręcznej i inne z dużą ilością. Czy warto wydawać pieniądze na model z dużą pamięcią podręczną? W przeszłości dodatkowa pamięć podręczna nie zawsze miała zauważalny wpływ na wydajność.

    Chociaż zawsze można znaleźć mierzalne różnice między dwoma procesorami o różnych rozmiarach pamięci podręcznej, całkowicie możliwe było kupowanie procesorów z mniejszą pamięcią podręczną w celu zaoszczędzenia pieniędzy. Jednak żaden procesor przed Core 2 Duo nie był dostępny z trzema różnymi opcjami pamięci podręcznej.

    Pentium 4 w swojej pierwszej generacji (Willamette, 180 nm) był wyposażony w 256 KB pamięci podręcznej, a w bardziej udanej drugiej generacji (Northwood, 130 nm) - już 512 KB pamięci podręcznej. W tamtym czasie na tych samych rdzeniach obliczeniowych produkowano tanie procesory Celeron z mniejszymi pamięciami podręcznymi. Celeron należy do pierwszej generacji produktów o tej samej bazie technologicznej dla modeli z wyższej półki i modeli niskobudżetowych, różniących się jedynie dostępną wielkością pamięci podręcznej i częstotliwościami FSB/rdzenia. Później dodano różnice w funkcjach, aby jeszcze bardziej zróżnicować segmenty rynku.

    Wraz z wypuszczeniem rdzenia Prescott 90 nm, pamięć podręczna L2 wzrosła do 1 MB, a procesor ten stał się podstawą linii procesorów Intel do komputerów stacjonarnych, aż do wprowadzenia 2 MB 65 nm Cedar Mill. Intel wykorzystał nawet dwa z tych rdzeni do stworzenia procesorów Pentium D 900 drugiej generacji. Jednak nawet wtedy większe prędkości zegara i większy rozmiar pamięci podręcznej nie miały większego znaczenia. Dziś sytuacja się zmieniła: lepsza wydajność Core 2 Duo (Conroe, 65 nm) i mniejsze zużycie energii wynikają w dużej mierze z rozmiaru pamięci podręcznej.

    AMD było bardzo powściągliwe w kwestii zwiększania rozmiaru pamięci podręcznej. Najprawdopodobniej wynika to z obszaru chipa (budżetu tranzystora), ponieważ liczba procesorów 65 nm nie jest w stanie zaspokoić zapotrzebowania rynku, a w przypadku mniej opłacalnych modeli 90 nm problem ten jest jeszcze bardziej dotkliwy. Z drugiej strony Intel ma tę zaletę, że produkuje wszystkie procesory głównego nurtu przy użyciu technologii procesowej 65 nm, a pojemność pamięci podręcznej L2 będzie nadal rosła. Przykładowo następna generacja Core 2 na rdzeniu Penryn wykonanym w procesie technologicznym 45 nm będzie wyposażona w aż 6 MB pamięci podręcznej L2. Czy można to postrzegać jako posunięcie marketingowe, czy też zwiększenie pojemności L2 faktycznie zapewni wzrost wydajności? Przyjrzyjmy się.

    Duża pamięć podręczna L2: marketing czy wzrost produktywności?

    Pamięci podręczne procesora pełnią bardzo specyficzną rolę: zmniejszają liczbę dostępów do pamięci poprzez buforowanie często używanych danych. Obecnie pojemność pamięci RAM waha się od 512 MB do 4 GB, a pojemność pamięci podręcznej waha się od 256 KB do 8 MB, w zależności od modelu. Jednak nawet niewielki rozmiar pamięci podręcznej wynoszący 256 lub 512 KB wystarczy, aby zapewnić wysoką wydajność, która jest dziś uważana za oczywistość.

    Istnieją różne sposoby organizowania hierarchii pamięci podręcznej. Większość nowoczesnych komputerów ma procesory z małą pamięcią podręczną pierwszego poziomu (L1, do 128 KB), która zwykle jest podzielona na pamięć podręczną danych i pamięć podręczną instrukcji. Większa pamięć podręczna L2 jest zwykle używana do przechowywania danych i jest współdzielona pomiędzy dwoma rdzeniami procesora Core 2 Duo, chociaż Athlon 64 X2 i Pentium D mają oddzielne pamięci podręczne na rdzeń. Pamięć podręczna L2 może działać wyłącznie lub włączająco, co oznacza, że ​​może przechowywać kopię zawartości pamięci podręcznej L1 lub nie. AMD wkrótce wprowadzi procesory z trzecim poziomem pamięci podręcznej, która w procesorach AMD Phenom będzie współdzielona pomiędzy czterema rdzeniami. Tego samego oczekuje się od architektury Nehalem, którą Intel wprowadzi w 2008 roku w celu zastąpienia obecnego Core 2.

    Pamięć podręczna L1 zawsze była częścią procesora, ale pamięć podręczna L2 była początkowo instalowana na płytach głównych, podobnie jak w przypadku wielu komputerów 486DX i Pentium. W przypadku pamięci podręcznej pierwszego poziomu zastosowano proste układy pamięci statycznej (SRAM, Static RAM). Wkrótce zostały one zastąpione przez potokową seryjną pamięć podręczną w procesorach Pentium, aż stało się możliwe zainstalowanie pamięci podręcznej na chipie. Pentium Pro pracujący z częstotliwością 150–200 MHz stał się pierwszym procesorem wyposażonym w 256 KB pamięci podręcznej L2 w chipie, bijąc rekord największego rozmiaru obudowy ceramicznej dla komputerów stacjonarnych i stacji roboczych. Pentium III dla Socket 370, pracujący w częstotliwościach od 500 MHz do 1,13 GHz, był pierwszym procesorem wyposażonym w 256 KB wbudowanej pamięci podręcznej L2, co zapewniało przewagę w zakresie opóźnień, ponieważ pamięć podręczna działała z szybkością procesora.

    Wbudowana pamięć podręczna L2 zapewniła znaczny wzrost wydajności w niemal każdej aplikacji. Wzrost wydajności okazał się na tyle znaczący, że pojawienie się zintegrowanej pamięci podręcznej L2 można nazwać najważniejszym czynnikiem wydajnościowym dla procesorów x86. Wyłączenie pamięci podręcznej L2 zmniejszy wydajność bardziej niż wyłączenie drugiego rdzenia dwurdzeniowego procesora.

    Jednak pamięć podręczna wpływa nie tylko na wydajność. Stało się potężnym narzędziem, które pozwala tworzyć różne modele procesorów dla segmentów low-end, mainstream i high-end, ponieważ producent może elastycznie dobierać procesory na podstawie odrzucenia i częstotliwości taktowania. Jeśli na krysztale nie ma defektów, można włączyć całą pamięć podręczną L2, a częstotliwości będą wysokie. Jeśli nie można osiągnąć pożądanych częstotliwości zegara, kryształ może stać się modelem podstawowym w linii high-end, na przykład Core 2 Duo 6000 z 4 MB pamięci podręcznej i niskimi częstotliwościami. Jeśli w pamięci podręcznej L2 występują defekty, producent ma możliwość wyłączenia jej części i stworzenia modelu podstawowego z mniejszym rozmiarem pamięci podręcznej, na przykład Core 2 Duo E4000 z 2 MB pamięci podręcznej L2 lub nawet Pentium Dual Core z tylko 1 MB pamięci podręcznej. Wszystko to prawda, ale pytanie brzmi: jak bardzo różnica w rozmiarze pamięci podręcznej wpływa na wydajność?

    Warianty Core 2 Duo

    Intel wprowadził na rynek szeroką gamę procesorów do komputerów stacjonarnych. Dziś nadal można znaleźć Pentium 4 i Pentium D, ale większość modeli jest zbudowana w oparciu o mikroarchitekturę Core. Nie polecamy procesorów Pentium 4 ani Pentium D, choć ich taktowanie do 3,8 GHz może wyglądać atrakcyjnie. Ale każdy procesor Core 2 o częstotliwości 2,2 GHz lub wyższej jest w stanie pokonać nawet najszybsze modele Pentium D (w rzeczywistości takie jak Athlon 64 X2), ponieważ Core 2 zapewnia znacznie lepsza wydajność na zegar .

    Dzięki niższym taktowaniu procesory Core 2 są bardziej energooszczędne. Jeśli topowe modele Pentium D 800 „pożerają” do 130 W, to próg 100 W przekracza jedynie Core 2 Extreme z czterema rdzeniami. Wszystkie procesory dwurdzeniowe zużywają nie więcej niż 65 W. Ponadto pobór mocy w stanie bezczynności procesorów Core 2 Duo jest jeszcze niższy, ponieważ częstotliwość w stanie bezczynności jest niższa (maksymalnie 1,2 GHz dla Core 2 Duo/Quad w porównaniu z 2,8 GHz dla Pentium D/4). Na zmniejszenie zużycia energii wpłynęła ulepszona konstrukcja tranzystora o zmniejszonych prądach upływowych.

    Obecnie dostępne są modele E i X. Modele E przeznaczone są na rynek masowy, natomiast modele X to edycje Extreme. Q oznacza cztery rdzenie, które Intel tworzy poprzez umieszczenie dwóch dwurdzeniowych kości w jednej fizycznej obudowie. Procesory E6000 są wyposażone w 4 MB pamięci podręcznej L2, jeśli ich numer modelu jest wyższy niż E6400 lub kończy się na 20 (na przykład E6320). Modele kończące się na 00 (np. E6600) działają na częstotliwości FSB 266 MHz (FSB1066), a modele kończące się na 50 (E6750) działają na częstotliwości FSB 333 MHz (FSB1333). Ten ostatni wymaga chipsetu P35 lub X38 i zapewnia nieco wyższą wydajność. Model E4000 działa z magistralą FSB 200 MHz (FSB800) i ma tylko 2 MB pamięci podręcznej L2. Wersje z 1 MB pamięci podręcznej sprzedawane są jako Pentium Dual Core E2140, E2160 i E2180 o częstotliwościach od 1,6 do 2,0 GHz. Poza nazwą i niektórymi funkcjami, które Intel wyłącza w tanich procesorach, wspomniane Pentium Dual Core są identyczne z Core 2 Duo.

    Charakterystyka procesorów Core 2 Duo
    Numer procesora 65 nm Pamięć podręczna Częstotliwość zegara FSB Technologia wirtualizacji Zaufana technologia wykonania
    E6850 4MB L2 3 GHz 333 MHz X X
    E6750 4MB L2 2,66 GHz 333 MHz X X
    E6700 4MB L2 2,66 GHz 266 MHz X
    E6600 4MB L2 2,40 GHz 266 MHz X
    E6550 4MB L2 2,33 GHz 333 MHz X X
    E6540 4MB L2 2,33 GHz 333 MHz X
    E6420 4MB L2 2,13 GHz 266 MHz X
    E6400 2MB L2 2,13 GHz 266 MHz X
    E6320 4MB L2 1,86 GHz 266 MHz X
    E6300 2MB L2 1,86 GHz 266 MHz X
    E4600 2MB L2 2,40 GHz 200 MHz
    E4500 2MB L2 2,20 GHz 200 MHz
    E4400 2MB L2 2 GHz 200 MHz
    E4300 2MB L2 1,80 GHz 200 MHz


    Platforma
    Procesor I Dwurdzeniowy procesor Intel Pentium E2160 (65 nm; 1800 MHz, 1 MB pamięci podręcznej L2) przy 2,4 GHz (266 MHz x9)
    Procesor II Intel Core 2 Duo E4400 (65 nm; 2000 MHz, 2 MB pamięci podręcznej L2) przy 2,4 GHz (266 MHz x9)
    Procesor III Intel Core 2 Duo X6800 (65 nm; 3000 MHz, 4 MB pamięci podręcznej L2) przy 2,4 GHz (266 MHz x9)
    Płyta główna Formuła ASUS Blitz, wersja: 1.0
    Chipset: Intel P35, BIOS 1101
    Pamięć Corsair CM2X1024-888C4D, 2x 1024 MB DDR2-800 (CL 4-4-4-12 2T)
    dysk twardy Western Digital Raptor WD1500ADFD, 150 GB, 10 000 obr./min, 16 MB pamięci podręcznej, SATA/150
    DVD-ROM Samsunga SH-S183
    Karta graficzna Zotac GeForce 8800 GTS, karta graficzna: GeForce 8800 GTS (500 MHz), pamięć: 320 MB GDDR3 (1600 MHz)
    Karta dźwiękowa Wbudowany
    jednostka mocy Enermax EG565P-VE, ATX 2.01, 510 W
    Oprogramowanie systemowe i sterowniki
    system operacyjny Windows XP Professional 5.10.2600 z dodatkiem Service Pack 2
    Wersja DirectX 9,0c (4.09.0000.0904)
    Sterowniki platformy Intel Wersja 8.3.1013
    sterownik karty graficznej nVidia Wymuś 162.18

    Testy i ustawienia

    Gry 3D
    Call of Duty 2 Wersja: 1.3 Detaliczna
    Tryb wideo: 1280x960
    Antyaliasing: wyłączony
    Karta graficzna: średnia
    Wersja demonstracyjna Timedemo2
    Ofiara Wersja: 1.3
    Tryb wideo: 1280x1024
    Jakość wideo: domyślna gra
    Vsync=wyłączone
    Test porównawczy: THG-Demo
    Wstrząs 4 Wersja: 1.2 (poprawka dwurdzeniowa)
    Tryb wideo: 1280x1024
    Jakość wideo: wysoka
    Mapa odpadów THG Timedemo
    timedemo demo8.demo 1 (1 = ładowanie tekstur)
    Audio
    Słabe MP3 Wersja 3.98 Beta 5
    Płyta audio „Terminator II SE”, 53 min
    pomachaj do mp3
    160 kb/s
    Wideo
    TMPEG 3.0 Express Wersja: 3.0.4.24 (bez dźwięku)
    pięść 5 minut DVD Terminator 2 SE (704x576) 16:9
    Wielowątkowość poprzez renderowanie
    DivX 6.7 Wersja: 6.6 (4 procesory logiczne)
    Profil: Profil wysokiej rozdzielczości
    1-przebieg, 3000 kbit/s
    Tryb kodowania: szalona jakość
    Ulepszona wielowątkowość
    bez dźwięku
    XviD 1.1.3 Wersja: 1.1.3
    Docelowy kwantyzator: 1,00
    Mainconcept H.264 v2 Wersja 2.1
    260 MB źródła MPEG-2 (1920x1080) 16:9
    Kodek: H.264
    Tryb: NTSC
    Dźwięk: AAC
    Profil: wysoki
    Strumień: Program
    Aplikacje
    WinRARA Wersja 3.70
    (303 MB, 47 plików, 2 foldery)
    Kompresja = najlepsza
    Słownik = 4096 kB
    Autodesk 3D Studio Max Wersja: 8.0
    Postacie „Dragon_Charater_rig”
    renderowanie HTDV 1920x1080
    Cinebench Wersja: R10
    1 procesor, x uruchomienie procesora
    PCMark05Pro Wersja: 1.2.0
    Testy procesora i pamięci
    Windows Media Player 10.00.00.3646
    Koder multimediów Windows 9.00.00.2980




    Wniosek

    Chociaż rozmiar pamięci podręcznej ma ograniczony wpływ na testy syntetyczne, takie jak PCMark05, różnica w wydajności dla większości rzeczywistych aplikacji była dość znacząca. W pierwszej chwili wydaje się to zaskakujące, gdyż doświadczenie pokazuje, że to właśnie testy syntetyczne dają najbardziej zauważalną różnicę w wydajności, co ma niewielki wpływ na rzeczywiste zastosowania.

    Odpowiedź jest prosta: rozmiar pamięci podręcznej jest bardzo ważny dla nowoczesnych procesorów z mikroarchitekturą Core 2 Duo. Użyliśmy 4 MB Core 2 Extreme X6800, 2 MB Core 2 Duo E4400 i Pentium Dual Core E2160, który jest procesorem Core 2 Duo z zaledwie 1 MB pamięci podręcznej L2. Wszystkie procesory pracowały na tej samej magistrali systemowej 266 MHz i z mnożnikiem 9x, aby osiągnąć częstotliwość 2400 MHz. Jedyną różnicą jest rozmiar pamięci podręcznej, ponieważ wszystkie nowoczesne procesory dwurdzeniowe, z wyjątkiem starego Pentium D, są wykonane z tych samych chipów. To, czym stanie się rdzeń, Core 2 Extreme Edition lub Pentium Dual Core, zależy od wydajności użytecznych kryształów (wad) lub zapotrzebowania rynku.

    Jeśli porównasz wyniki strzelanek 3D Prey i Quake 4, które są typowymi aplikacjami do gier, różnica w wydajności między 1 a 4 MB wynosi w przybliżeniu jeden krok częstotliwości. To samo dotyczy testów kodowania wideo dla kodeków DivX 6.6 i XviD 1.1.2, a także archiwizatora WinRAR 3.7. Jednak aplikacje intensywnie obciążające procesor, takie jak 3DStudio Max 8, Lame MP3 Encoder lub H.264 Encoder V2 firmy MainConcept, nie odniosą większych korzyści z większych rozmiarów pamięci podręcznej.

    Jednak podejście Intela, czyli wykorzystanie całego dostępnego budżetu tranzystorów, który wzrósł w trakcie przejścia z technologii procesowej 65 nm na 45 nm, ma pewne znaczenie dla mikroarchitektury Core 2 Duo. Pamięć podręczna L2 tych procesorów działa bardzo wydajnie, zwłaszcza biorąc pod uwagę, że jest współdzielona przez dwa rdzenie. Dlatego pamięć podręczna neutralizuje wpływ różnych częstotliwości pamięci i zapobiega „wąskiemu gardłu” w postaci FSB. I robi to wyjątkowo dobrze, ponieważ testy wyraźnie pokazują, że wydajność procesora z jednym megabajtem pamięci podręcznej jest niska.

    Z tego punktu widzenia zwiększenie rozmiaru pamięci podręcznej L2 z 4 MB do maksymalnie 6 MB dla nadchodzących dwurdzeniowych procesorów Penryn 45 nm (linia Core 2 Duo E8000) ma sens. Skrócenie procesu produkcyjnego z 65 do 45 nm pozwala Intelowi zwiększyć budżet tranzystorów, a dzięki zwiększeniu rozmiaru pamięci podręcznej po raz kolejny odnotujemy wzrost wydajności. Jednak Intel skorzysta z różnych opcji procesorów z 6, 4, 2, a nawet 1 MB pamięci podręcznej L2. Dzięki wielu opcjom firma Intel może wykorzystać więcej matryc na płytkę pomimo sporadycznych defektów, które w przeciwnym razie wylądowałyby w koszu na śmieci. Jak widzimy, duży rozmiar pamięci podręcznej jest ważny nie tylko dla wydajności, ale także dla zysków Intela.

    Wszyscy użytkownicy doskonale zdają sobie sprawę z takich elementów komputera, jak procesor, który odpowiada za przetwarzanie danych, a także pamięć o dostępie swobodnym (RAM lub RAM), która odpowiada za ich przechowywanie. Ale nie każdy zapewne wie, że istnieje również pamięć podręczna procesora (Cache CPU), czyli pamięć RAM samego procesora (tzw. ultra-RAM).

    Co skłoniło projektantów komputerów do stosowania pamięci dedykowanej dla procesora? Czy pojemność pamięci RAM komputera nie jest wystarczająca?

    Rzeczywiście, przez długi czas komputery osobiste radziły sobie bez pamięci podręcznej. Ale, jak wiadomo, procesor jest najszybszym urządzeniem w komputerze osobistym, a jego prędkość wzrasta z każdą nową generacją procesora. Obecnie jego prędkość mierzy się w miliardach operacji na sekundę. Jednocześnie standardowa pamięć RAM nie zwiększyła znacząco swojej wydajności podczas swojej ewolucji.

    Ogólnie rzecz biorąc, istnieją dwie główne technologie układów pamięci – pamięć statyczna i pamięć dynamiczna. Nie wnikając w szczegóły ich konstrukcji, powiemy jedynie, że pamięć statyczna w odróżnieniu od pamięci dynamicznej nie wymaga regeneracji; Ponadto pamięć statyczna wykorzystuje 4-8 tranzystorów na jeden bit informacji, podczas gdy pamięć dynamiczna wykorzystuje 1-2 tranzystory. W związku z tym pamięć dynamiczna jest znacznie tańsza niż pamięć statyczna, ale jednocześnie znacznie wolniejsza. Obecnie kości RAM produkowane są w oparciu o pamięć dynamiczną.

    Przybliżona ewolucja stosunku szybkości procesorów i pamięci RAM:

    Gdyby więc procesor cały czas pobierał informacje z pamięci RAM, musiałby czekać na powolną pamięć dynamiczną i cały czas byłby bezczynny. W tym samym przypadku, gdyby jako pamięć RAM użyto pamięci statycznej, koszt komputera wzrósłby kilkukrotnie.

    Dlatego wypracowano rozsądny kompromis. Większość pamięci RAM pozostała dynamiczna, a procesor otrzymał własną szybką pamięć podręczną opartą na statycznych układach pamięci. Jego objętość jest stosunkowo niewielka - na przykład objętość pamięci podręcznej drugiego poziomu wynosi tylko kilka megabajtów. Warto jednak pamiętać, że cała pamięć RAM pierwszych komputerów IBM PC zajmowała mniej niż 1 MB.

    Ponadto na celowość wprowadzenia technologii buforowania wpływa również fakt, że różne aplikacje zlokalizowane w pamięci RAM w różny sposób obciążają procesor, a w efekcie pojawia się dużo danych, które wymagają priorytetowego przetwarzania w porównaniu do innych.

    Historia pamięci podręcznej

    Ściśle rzecz biorąc, zanim pamięć podręczna przeniosła się do komputerów osobistych, z powodzeniem była stosowana w superkomputerach już od kilkudziesięciu lat.

    Po raz pierwszy w komputerze PC opartym na procesorze i80386 pojawiła się pamięć podręczna o wielkości zaledwie 16 KB. Obecnie nowoczesne procesory korzystają z różnych poziomów pamięci podręcznej, od pierwszego (najszybsza pamięć podręczna o najmniejszym rozmiarze - zwykle 128 KB) do trzeciego (najwolniejsza pamięć podręczna o największym rozmiarze - do kilkudziesięciu MB).

    Początkowo zewnętrzna pamięć podręczna procesora znajdowała się na osobnym chipie. Z biegiem czasu spowodowało to jednak, że magistrala znajdująca się pomiędzy pamięcią podręczną a procesorem stała się wąskim gardłem, spowalniając wymianę danych. W nowoczesnych mikroprocesorach zarówno pierwszy, jak i drugi poziom pamięci podręcznej znajdują się w samym rdzeniu procesora.

    Przez długi czas procesory miały tylko dwa poziomy pamięci podręcznej, ale procesor Intel Itanium jako pierwszy posiadał pamięć podręczną trzeciego poziomu, wspólną dla wszystkich rdzeni procesorów. Istnieją również opracowania procesorów z czteropoziomową pamięcią podręczną.

    Architektury i zasady pamięci podręcznej

    Obecnie znane są dwa główne typy organizacji pamięci podręcznej, które wywodzą się z pierwszych osiągnięć teoretycznych w dziedzinie cybernetyki – architektury Princeton i Harvard. Architektura Princeton zakłada pojedynczą przestrzeń pamięci do przechowywania danych i poleceń, natomiast architektura Harvardu oznacza oddzielne przestrzenie. Większość procesorów komputerów osobistych x86 korzysta z oddzielnego typu pamięci podręcznej. Ponadto we współczesnych procesorach pojawił się także trzeci rodzaj pamięci podręcznej – tzw. asocjacyjny bufor translacyjny, mający na celu przyspieszenie konwersji adresów pamięci wirtualnej systemu operacyjnego na adresy pamięci fizycznej.

    Uproszczony schemat interakcji pamięci podręcznej i procesora można opisać w następujący sposób. Najpierw sprawdza obecność informacji potrzebnych procesorowi w najszybszej pamięci podręcznej pierwszego poziomu, następnie w pamięci podręcznej drugiego poziomu itd. Jeśli na żadnym poziomie pamięci podręcznej nie zostaną znalezione niezbędne informacje, nazywa się to błędem lub brakiem pamięci podręcznej. Jeśli w ogóle nie ma informacji w pamięci podręcznej, procesor musi je pobrać z pamięci RAM lub nawet z pamięci zewnętrznej (z dysku twardego).

    Kolejność, w jakiej procesor szuka informacji w pamięci:

    W ten sposób Procesor wyszukuje informacje

    Aby kontrolować działanie pamięci podręcznej i jej interakcję z jednostkami obliczeniowymi procesora, a także pamięcią RAM, istnieje specjalny kontroler.

    Schemat organizacji interakcji rdzenia procesora, pamięci podręcznej i pamięci RAM:

    Kontroler pamięci podręcznej jest kluczowym ogniwem pomiędzy procesorem, pamięcią RAM i pamięcią podręczną

    Należy zaznaczyć, że buforowanie danych to złożony proces, w którym wykorzystuje się wiele technologii i algorytmów matematycznych. Do podstawowych koncepcji stosowanych w buforowaniu należą metody zapisu w pamięci podręcznej i architektura skojarzeń pamięci podręcznej.

    Metody zapisu w pamięci podręcznej

    Istnieją dwie główne metody zapisywania informacji w pamięci podręcznej:

    1. Metoda zapisu zwrotnego – dane zapisywane są najpierw do pamięci podręcznej, a następnie, gdy zaistnieją określone warunki, do pamięci RAM.
    2. Metoda zapisu – dane są zapisywane jednocześnie do pamięci RAM i pamięci podręcznej.

    Architektura skojarzeń pamięci podręcznej

    Architektura skojarzeń pamięci podręcznej definiuje sposób, w jaki dane z pamięci RAM są mapowane do pamięci podręcznej. Główne opcje architektury skojarzeń buforowania to:

    1. Pamięć podręczna mapowana bezpośrednio - określona sekcja pamięci podręcznej odpowiada za określoną sekcję pamięci RAM
    2. W pełni asocjacyjna pamięć podręczna - dowolna część pamięci podręcznej może być powiązana z dowolną częścią pamięci RAM
    3. Mieszana pamięć podręczna (zestaw asocjacyjny)

    Różne poziomy pamięci podręcznej mogą zazwyczaj wykorzystywać różne architektury skojarzeń pamięci podręcznej. Bezpośrednio mapowana pamięć podręczna RAM jest najszybszą opcją buforowania, dlatego ta architektura jest zwykle używana w przypadku dużych pamięci podręcznych. Z kolei w pełni skojarzeniowa pamięć podręczna ma mniej błędów pamięci podręcznej (chybień).

    Wniosek

    W tym artykule zapoznałeś się z koncepcją pamięci podręcznej, architekturą pamięci podręcznej i metodami buforowania oraz dowiedziałeś się, jak wpływa to na wydajność współczesnego komputera. Obecność pamięci podręcznej może znacznie zoptymalizować działanie procesora, skrócić jego czas bezczynności, a w konsekwencji zwiększyć wydajność całego systemu.

    Wszystkie procesory od końca lat 90. mają wewnętrzną pamięć podręczną (lub po prostu pamięć podręczną). Pamięć podręczna to szybka pamięć, do której przenoszone są instrukcje i dane przetwarzane bezpośrednio przez procesor.

    Nowoczesne procesory mają wbudowaną pamięć podręczną dwóch poziomów - pierwszego (L1) i drugiego (L2). Procesor jest nieco szybszy przy zawartości pamięci podręcznej L1, podczas gdy pamięć podręczna L2 jest zwykle nieco większa. Dostęp do pamięci podręcznej jest możliwy bez stanu oczekiwania, tj. Pamięć podręczna poziomu 1 (pamięć podręczna na chipie) działa z szybkością procesora.

    Oznacza to, że jeśli dane potrzebne procesorowi znajdują się w pamięci podręcznej, nie występują opóźnienia w przetwarzaniu. W przeciwnym razie procesor musi pobierać dane z pamięci głównej, co znacznie zmniejsza wydajność systemu.

    Aby jakościowo zrozumieć zasadę działania pamięci podręcznej obu poziomów, rozważmy jako przykład codzienną sytuację.

    Codziennie o tej samej porze przychodzisz do kawiarni na lunch i zawsze siadasz przy tym samym stole. Zawsze zamawiaj standardowy zestaw trzech dań.

    Kelner biegnie do kuchni, kucharz kładzie je na tacy, po czym przynoszą zamówienie. I tak, powiedzmy, trzeciego dnia kelner, żeby nie musieć znowu biegać do kuchni, spotyka Cię o wyznaczonej godzinie z gotowym, gorącym obiadem na tacy.

    Nie musisz czekać na swoje zamówienie i oszczędzasz mnóstwo czasu. Taca z Twoimi naczyniami to skrytka pierwszego poziomu. Ale czwartego dnia nagle chcesz dodać kolejne danie, powiedzmy deser.

    Choć o wyznaczonej godzinie czekała już na Państwa taca z zamówieniem, kelner i tak musiał biec do kuchni na deser.

    A na piątym - znowu menu składające się z trzech pozycji. Na szóstym – znowu deser, ale inny niż poprzednie. A kelner, nie wiedząc, jaki deser chcesz zamówić (a nawet nie wiedząc, czy cokolwiek zamówisz), decyduje się na kolejny krok: obok Twojego stołu stawia szafkę z kilkoma rodzajami deserów.

    A jeśli wyrazisz chęć, wszystko jest pod ręką, nie musisz biegać do kuchni. Szafka na desery to skrytka drugiego poziomu.

    Wydajność procesora w znacznym stopniu zależy od wielkości pamięci podręcznej L1 (od 16 do 128 KB) i L2 (od 64 KB do 512 KB, w Pentium III Heop i AMD Opteron do 4 MB).

    Procesory Intel Pentium III i oparte na nich procesory Celeron mają rozmiar pamięci podręcznej L1 wynoszącej 32 KB. Intel Pentium 4, a także oparte na nim wersje Celeron i Cheop, mają tylko 20 KB. Procesory AMD Duron, Athlon (w tym XP/MP) i Opteron, a także VIA SZ zawierają 128 KB pamięci podręcznej L1.

    Nowoczesne procesory dwurdzeniowe mają pamięć podręczną pierwszego poziomu dla każdego rdzenia osobno, dlatego czasami w opisie pamięci podręcznej możemy zobaczyć liczbę 128x2. Oznacza to, że każdy rdzeń procesora ma 128 KB pamięci podręcznej L1.

    Rozmiar pamięci podręcznej L1 jest ważny dla uzyskania wysokiej wydajności w większości typowych zadań (aplikacje biurowe, gry, większość aplikacji serwerowych itp.). Jego skuteczność jest szczególnie duża w przypadku obliczeń wielowątkowych (na przykład przetwarzania wideo).

    Jest to jeden z powodów, dla których Pentium 4 jest stosunkowo nieefektywny w większości typowych zastosowań (chociaż jest to kompensowane przez jego wysoką częstotliwość taktowania). Pamięć podręczna L1 zawsze pracuje (wymienia informacje z rdzeniem procesora) z częstotliwością wewnętrzną procesora.

    Natomiast pamięć podręczna L2 w różnych modelach procesorów działa z różnymi częstotliwościami (i odpowiednio wydajnością). Począwszy od Intel Pentium II, wiele procesorów korzystało z pamięci podręcznej L2 działającej z połową wewnętrznej częstotliwości procesora.

    Rozwiązanie to zastosowano w przestarzałych procesorach Intel Pentium III (do 550 MHz) i przestarzałym AMD Athlon (w niektórych z nich wewnętrzna pamięć podręczna L2 pracowała z jedną trzecią częstotliwości rdzenia procesora). Rozmiar pamięci podręcznej L2 również różni się w zależności od procesora.

    W starszych i niektórych nowszych procesorach Intel Pentium III wielkość pamięci podręcznej L2 wynosi 512 KB, w pozostałych procesorach Pentium III 256 KB. Procesor Intel Celeron oparty na Pentium III był dostępny z 128 i 256 KB pamięci podręcznej L2, podczas gdy procesor oparty na Pentium 4 był dostępny tylko z 128 KB. W różnych wersjach procesora Intel Pentium 4 z procesorem Xeon dostępnych jest do 4 MB pamięci podręcznej L2.

    Nowe procesory Pentium 4 (niektóre serie o częstotliwości 2000 MHz i wszystkie dla wyższych częstotliwości) mają 512 KB pamięci podręcznej L2, pozostałe Pentium 4 mają 256 KB. Procesory Xeop (oparte na Pentium 4) posiadają 256 lub 512 KB pamięci podręcznej L2.

    Ponadto mają także pamięć podręczną L3 trzeciego poziomu. Zintegrowana pamięć podręczna L3 w połączeniu z szybką magistralą systemową tworzy szybki kanał wymiany danych z pamięcią systemową.

    Z reguły tylko procesory do rozwiązań serwerowych lub specjalne modele procesorów „do komputerów stacjonarnych” są wyposażone w pamięć podręczną L3. Na przykład linie procesorów, takie jak Xeon DP, Itanium 2 i Xeon MP, mają pamięć podręczną L3.

    Procesor AMD Duron ma 128 KB pamięci podręcznej L1 i 64 KB pamięci podręcznej L2. Procesory Athlon (z wyjątkiem najstarszego), Athlon MP i większość wariantów Athlon XP mają 128 KB pamięci podręcznej L1 i 256 KB pamięci podręcznej L2, a najnowszy Athlon XP (2500+, 2800+, 3000+ i wyższe) ma 512 KB pamięci L2 Pamięć podręczna. AMD Opteron zawiera 1 MB pamięci podręcznej L2.

    Najnowsze modele procesorów Intel Pentium D, Intel Pentium M, Intel Core 2 Duo dostępne są z 6 MB pamięci podręcznej L2, a Core 2 Quad - 12 MB pamięci podręcznej L2.

    Najnowszy procesor Intel Core i7 w momencie pisania tej książki ma 64 KB pamięci podręcznej L1 dla każdego z 4 rdzeni, a także 256 KB pamięci L2 dla każdego rdzenia. Oprócz pamięci podręcznej pierwszego i drugiego poziomu procesor ma także wspólną dla wszystkich rdzeni pamięć podręczną trzeciego poziomu, równą 8 MB.

    W przypadku procesorów, które mogą mieć różne rozmiary pamięci podręcznej L2 (lub w przypadku Intel Xeon MP - L3) dla tego samego modelu, wielkość ta musi być wskazana w momencie sprzedaży (oczywiście od tego zależy cena procesora). Jeśli procesor sprzedawany jest w opakowaniu „pudełkowym” (dostawa w pudełku), zwykle jest na nim wskazany rozmiar pamięci podręcznej.

    W przypadku normalnych zadań użytkownika (w tym gier) prędkość pamięci podręcznej L2 jest ważniejsza niż jej wielkość; wręcz przeciwnie, w przypadku zadań serwerowych ważniejsza jest głośność. Najbardziej produktywne serwery, zwłaszcza te z dużą ilością pamięci RAM (kilka gigabajtów), wymagają maksymalnego rozmiaru i maksymalnej szybkości pamięci podręcznej L2.

    Wersje Cheop procesorów Pentium III pozostają pod tymi parametrami niedoścignione. (Procesor Xeon MP w dalszym ciągu okazuje się bardziej produktywny w zadaniach serwerowych niż Pentium III Xeon, ze względu na wyższą częstotliwość taktowania samego procesora i szyny pamięci.) Z powyższego wnioskujemy: pamięć podręczna poprawia interakcję między szybki procesor i wolniejszą pamięć RAM, a także pozwala zminimalizować okresy oczekiwania występujące podczas przetwarzania danych. Decydującą rolę odgrywa w tym pamięć podręczna L2 umieszczona na chipie procesora.

    Prawie wszyscy programiści wiedzą, że pamięć podręczna procesora to mała, ale szybka pamięć, w której przechowywane są dane z ostatnio odwiedzanych obszarów pamięci - definicja jest krótka i dość dokładna. Jednak znajomość nudnych szczegółów na temat mechanizmów pamięci podręcznej jest konieczna, aby zrozumieć czynniki wpływające na wydajność kodu.

    W tym artykule przyjrzymy się szeregowi przykładów ilustrujących różne cechy pamięci podręcznych i ich wpływ na wydajność. Przykłady będą w języku C#; wybór języka i platformy nie ma większego wpływu na ocenę wydajności i wnioski końcowe. Naturalnie, w rozsądnych granicach, jeśli wybierzesz język, w którym odczytanie wartości z tablicy jest równoznaczne z dostępem do tablicy mieszającej, nie otrzymasz żadnych możliwych do zinterpretowania wyników. Przypisy tłumacza pisane są kursywą.

    Habracut - - -

    Przykład 1: Dostęp do pamięci i wydajność

    Jak myślisz, o ile szybszy jest drugi cykl niż pierwszy?
    int arr = nowy int;

    // Pierwszy
    for (int i = 0; tj< arr.Length; i++) arr[i] *= 3;

    // drugi
    for (int i = 0; tj< arr.Length; i += 16) arr[i] *= 3;


    Pierwsza pętla mnoży wszystkie wartości w tablicy przez 3, druga pętla mnoży tylko co szesnastą wartość. Drugi cykl kończy się dopiero 6% pracy pierwszy cykl, ale na nowoczesnych maszynach oba cykle wykonywane są w przybliżeniu w równym czasie: 80 ms I 78 ms odpowiednio (na moim komputerze).

    Rozwiązanie jest proste - dostęp do pamięci. Szybkość tych pętli zależy przede wszystkim od szybkości podsystemu pamięci, a nie od szybkości mnożenia liczb całkowitych. Jak zobaczymy w następnym przykładzie, liczba dostępów do pamięci RAM jest taka sama zarówno w pierwszym, jak i drugim przypadku.

    Przykład 2: Wpływ linii pamięci podręcznej

    Zagłębmy się w szczegóły i wypróbujmy inne wartości kroków, a nie tylko 1 i 16:
    for (int i = 0; tj< arr.Length; i += K /* шаг */ ) arr[i] *= 3;

    Oto czasy działania tej pętli dla różnych wartości kroku K:

    Należy pamiętać, że przy wartościach kroku od 1 do 16 czas pracy pozostaje praktycznie niezmieniony. Ale przy wartościach większych niż 16 czas działania zmniejsza się o około połowę za każdym razem, gdy podwajamy krok. Nie oznacza to, że pętla w magiczny sposób zacznie działać szybciej, po prostu liczba iteracji również maleje. Kluczową kwestią jest ten sam czas pracy z wartościami kroków od 1 do 16.

    Powodem tego jest to, że nowoczesne procesory nie uzyskują dostępu do pamięci po bajcie, ale raczej w małych blokach zwanych liniami pamięci podręcznej. Zwykle rozmiar ciągu wynosi 64 bajty. Kiedy czytasz jakąkolwiek wartość z pamięci, co najmniej jedna linia pamięci podręcznej trafia do pamięci podręcznej. Późniejszy dostęp do dowolnej wartości z tego wiersza jest bardzo szybki.

    Ponieważ 16 wartości int zajmuje 64 bajty, pętle z krokami od 1 do 16 uzyskują dostęp do tej samej liczby linii pamięci podręcznej, a dokładniej do wszystkich linii pamięci podręcznej tablicy. W kroku 32 dostęp następuje do co drugiej linii, w kroku 64 do co czwartej.

    Zrozumienie tego jest bardzo ważne w przypadku niektórych technik optymalizacji. Liczba dostępów do niego zależy od lokalizacji danych w pamięci. Na przykład niewyrównane dane mogą wymagać dwóch dostępów do pamięci głównej zamiast jednego. Jak dowiedzieliśmy się powyżej, prędkość robocza będzie dwukrotnie niższa.

    Przykład 3: Rozmiary pamięci podręcznej poziomu 1 i 2 (L1 i L2)

    Nowoczesne procesory mają zazwyczaj dwa lub trzy poziomy pamięci podręcznej, zwykle nazywane L1, L2 i L3. Aby sprawdzić rozmiary pamięci podręcznych na różnych poziomach, możesz użyć narzędzia CoreInfo lub funkcji API systemu Windows GetLogicalProcessorInfo. Obie metody dostarczają również informacji o rozmiarze linii pamięci podręcznej dla każdego poziomu.

    Na moim komputerze CoreInfo zgłasza 32 KB pamięci podręcznej danych L1, 32 KB pamięci podręcznej instrukcji L1 i 4 MB pamięci podręcznej danych L2. Każdy rdzeń ma własne osobiste pamięci podręczne L1, pamięci podręczne L2 są współdzielone przez każdą parę rdzeni:

    Mapa procesora logicznego do pamięci podręcznej: *--- Pamięć podręczna danych 0, poziom 1, 32 KB, Assoc 8, Rozmiar linii 64 *--- Pamięć podręczna instrukcji 0, poziom 1, 32 KB, Assoc 8, Rozmiar linii 64 -*-- Pamięć podręczna danych 1, poziom 1, 32 KB, Assoc 8, LineSize 64 -*-- Instrukcja Cache 1, poziom 1, 32 KB, Assoc 8, LineSize 64 **-- Unified Cache 0, poziom 2, 4 MB, Assoc 16, LineSize 64 --*- Pamięć podręczna danych 2, poziom 1, 32 KB, Assoc 8, rozmiar linii 64 --*- Pamięć podręczna instrukcji 2, poziom 1, 32 KB, Assoc 8, rozmiar linii 64 ---* Pamięć podręczna danych 3, poziom 1, 32 KB, Assoc 8, LineSize 64 ---* Instrukcja Cache 3, poziom 1, 32 KB, Assoc 8, LineSize 64 --** Unified Cache 1, poziom 2, 4 MB, Assoc 16, LineSize 64
    Sprawdźmy tę informację eksperymentalnie. Aby to zrobić, przejrzyjmy naszą tablicę, zwiększając co 16 wartość – łatwy sposób na zmianę danych w każdej linii pamięci podręcznej. Kiedy dotrzemy do końca, wracamy do początku. Sprawdźmy różne rozmiary tablic; powinniśmy zauważyć spadek wydajności, gdy tablica nie mieści się już w pamięciach podręcznych o różnych poziomach.

    Kod to:

    int kroki = 64 * 1024 * 1024; // liczba iteracji
    int długośćMod = arr.Length - 1; // rozmiar tablicy -- potęga dwójki

    for (int i = 0; tj< steps; i++)
    {
    // x & długośćMod = x % arr.Length, ponieważ potęgi dwójki
    arr[(i * 16) & długośćMod]++;
    }


    Wyniki testu:

    Na moim komputerze zauważalne są spadki wydajności po 32 KB i 4 MB - są to rozmiary pamięci podręcznych L1 i L2.

    Przykład 4: Równoległość instrukcji

    Teraz spójrzmy na coś innego. Twoim zdaniem, która z tych dwóch pętli wykona się szybciej?
    int kroki = 256 * 1024 * 1024;
    int a = nowy int;

    // Pierwszy
    for (int i = 0; tj< steps; i++) { a++; a++; }

    // drugi
    for (int i = 0; tj< steps; i++) { a++; a++; }


    Okazuje się, że druga pętla działa niemal dwukrotnie szybciej, przynajmniej na wszystkich testowanych przeze mnie maszynach. Dlaczego? Ponieważ polecenia wewnątrz pętli mają różne zależności danych. Pierwsze polecenia mają następujący łańcuch zależności:

    W drugim cyklu zależności są następujące:

    Części funkcjonalne nowoczesnych procesorów są w stanie wykonywać jednocześnie pewną liczbę określonych operacji, zwykle niezbyt dużą. Przykładowo możliwy jest równoległy dostęp do danych z pamięci podręcznej L1 pod dwoma adresami, a także jednoczesne wykonywanie dwóch prostych instrukcji arytmetycznych. W pierwszym cyklu procesor nie może wykorzystać tych możliwości, ale w drugim już tak.

    Przykład 5: Łączność pamięci podręcznej

    Jednym z kluczowych pytań, na które należy odpowiedzieć projektując pamięć podręczną, jest to, czy dane z określonego obszaru pamięci można przechowywać w dowolnych komórkach pamięci podręcznej, czy tylko w niektórych z nich. Trzy możliwe rozwiązania:
    1. Bezpośrednia pamięć podręczna mapowania,Dane każdej linii pamięci podręcznej w pamięci RAM są przechowywane tylko w jednej, predefiniowanej lokalizacji pamięci podręcznej. Najprostszy sposób obliczenia mapowania to: indeks_wiersza_w_pamięci % liczba_komórek_pamięci_cache. Dwie linie odwzorowane na tę samą komórkę nie mogą znajdować się w pamięci podręcznej w tym samym czasie.
    2. Pamięć podręczna częściowo skojarzeniowa z N wpisami, każda linia może być przechowywana w N różnych lokalizacjach pamięci podręcznej. Na przykład w pamięci podręcznej z 16 wpisami wiersz może być przechowywany w jednej z 16 komórek tworzących grupę. Zwykle wiersze z równymi najmniej znaczącymi bitami indeksów dzielą jedną grupę.
    3. W pełni asocjacyjna pamięć podręczna, dowolna linia może być przechowywana w dowolnej lokalizacji pamięci podręcznej. Rozwiązanie jest w swoim zachowaniu równoważne tabeli mieszającej.
    Pamięci podręczne mapowane bezpośrednio są podatne na rywalizację, na przykład gdy dwa wiersze konkurują o tę samą komórkę, naprzemiennie wykluczają się z pamięci podręcznej, wydajność jest bardzo niska. Z drugiej strony, w pełni asocjacyjne pamięci podręczne, choć pozbawione tej wady, są bardzo złożone i kosztowne w implementacji. Częściowo asocjacyjne pamięci podręczne stanowią typowy kompromis pomiędzy złożonością implementacji a wydajnością.

    Na przykład na moim komputerze pamięć podręczna L2 o wielkości 4 MB to 16-wejściowa pamięć podręczna częściowo skojarzona. Cała pamięć RAM jest podzielona na zestawy linii według najmniej znaczących bitów ich indeksów, linie z każdego zestawu konkurują o jedną grupę 16 komórek pamięci podręcznej L2.

    Ponieważ pamięć podręczna L2 ma 65 536 komórek (4 * 2 20/64), a każda grupa składa się z 16 komórek, mamy w sumie 4096 grup. Zatem dolne 12 bitów indeksu wiersza określa, do której grupy należy ten wiersz (2 12 = 4096). W rezultacie wiersze z adresami będącymi wielokrotnościami 262 144 (4096 * 64) dzielą tę samą grupę 16 komórek i konkurują w niej o miejsce.

    Aby efekty skojarzeń zadziałały, musimy stale uzyskiwać dostęp do dużej liczby wierszy z tej samej grupy, na przykład za pomocą następującego kodu:

    public static long UpdateEveryKthByte (bajt arr, int K)
    {
    stała int rep = 1024 * 1024; // liczba iteracji

    Stoper sw = Stoper.StartNew();

    int p = 0;
    for (int i = 0; tj< rep; i++)
    {
    arr[p]++;

    P += K; if (p >= długość tablicy) p = 0;
    }

    Przeł.Stop();
    return sw.ElapsedMillisekundy;
    }


    Metoda zwiększa każdy K-ty element tablicy. Kiedy dotrzemy do końca, zaczynamy od nowa. Po dość dużej liczbie iteracji (2 20) zatrzymujemy się. Zrobiłem przebiegi dla różnych rozmiarów tablic i wartości kroku K (niebieski – długi czas działania, biały – krótki):

    Niebieskie obszary odpowiadają przypadkom, gdy przy ciągłych zmianach danych pamięć podręczna nie jest w stanie pomieścić wszystkie potrzebne dane na raz. Jasnoniebieski kolor oznacza czas działania około 80 ms, prawie biały - 10 ms.

    Zajmijmy się niebieskimi obszarami:

    1. Dlaczego pojawiają się pionowe linie? Pionowe linie odpowiadają wartościom kroków, przy których uzyskuje się dostęp do zbyt wielu wierszy (więcej niż 16) z jednej grupy. W przypadku tych wartości 16-wpisowa pamięć podręczna mojego komputera nie może pomieścić wszystkich niezbędnych danych.

      Niektóre z nieprawidłowych wartości kroków to potęgi dwójki: 256 i 512. Weźmy na przykład krok 512 i tablicę 8 MB. W tym kroku w tablicy znajdują się 32 sekcje (8 * 2 20 / 262 144), które konkurują ze sobą o komórki w 512 grupach pamięci podręcznej (262 144 / 512). Są 32 sekcje, ale w pamięci podręcznej jest tylko 16 komórek dla każdej grupy, więc nie ma wystarczającej ilości miejsca dla wszystkich.

      Inne wartości kroków, które nie są potęgami dwójki, są po prostu pechowe, co powoduje dużą liczbę trafień do tych samych grup pamięci podręcznej, a także prowadzi do pojawienia się na rysunku pionowych niebieskich linii. W tym miejscu miłośnicy teorii liczb proszeni są o zastanowienie się.

    2. Dlaczego pionowe linie pękają na granicy 4 MB? Gdy rozmiar tablicy wynosi 4 MB lub mniej, 16-wpisowa pamięć podręczna zachowuje się jak w pełni asocjacyjna pamięć podręczna, to znaczy może pomieścić wszystkie dane w tablicy bez konfliktów. Nie więcej niż 16 obszarów walczy o jedną grupę pamięci podręcznej (262 144 * 16 = 4 * 2 20 = 4 MB).
    3. Dlaczego w lewym górnym rogu znajduje się duży niebieski trójkąt? Ponieważ przy małym kroku i dużej tablicy pamięć podręczna nie jest w stanie zmieścić wszystkich niezbędnych danych. Stopień asocjatywności pamięci podręcznej odgrywa tutaj drugorzędną rolę; ograniczenie jest związane z wielkością pamięci podręcznej L2.

      Na przykład przy rozmiarze tablicy 16 MB i kroku 128 uzyskujemy dostęp do co 128 bajtu, modyfikując w ten sposób co drugą linię pamięci podręcznej tablicy. Aby przechowywać co drugą linię w pamięci podręcznej, potrzebujesz 8 MB pamięci podręcznej, ale na moim komputerze mam tylko 4 MB.

      Nawet gdyby pamięć podręczna była w pełni skojarzeniowa, nie pozwoliłaby na przechowywanie w niej 8 MB danych. Należy zauważyć, że w omawianym już przykładzie z krokiem 512 i rozmiarem tablicy 8 MB potrzebujemy tylko 1 MB pamięci podręcznej do przechowywania wszystkich niezbędnych danych, ale jest to niemożliwe ze względu na niewystarczającą asocjatywność pamięci podręcznej.

    4. Dlaczego lewa strona trójkąta stopniowo zyskuje na intensywności? Maksymalna intensywność występuje przy wartości kroku wynoszącej 64 bajty, która jest równa rozmiarowi linii pamięci podręcznej. Jak widzieliśmy w pierwszym i drugim przykładzie, sekwencyjny dostęp do tego samego wiersza nie kosztuje prawie nic. Powiedzmy, że z krokiem 16 bajtów mamy cztery dostępy do pamięci w cenie jednego.

      Ponieważ liczba iteracji jest taka sama w naszym teście dla dowolnej wartości kroku, tańszy krok skutkuje krótszym czasem wykonania.

    Odkryte efekty utrzymują się przy dużych wartościach parametrów:

    Łączność pamięci podręcznej to interesująca rzecz, która może objawiać się w pewnych warunkach. W przeciwieństwie do innych problemów omówionych w tym artykule, nie jest on tak poważny. Na pewno nie jest to coś, co wymaga ciągłej uwagi podczas pisania programów.

    Przykład 6: fałszywe partycjonowanie pamięci podręcznej

    Na maszynach wielordzeniowych możesz napotkać inny problem - spójność pamięci podręcznej. Rdzenie procesorów mają częściowo lub całkowicie oddzielne pamięci podręczne. Na moim komputerze pamięci podręczne L1 są oddzielne (jak zwykle) i są też dwie pamięci podręczne L2 współdzielone przez każdą parę rdzeni. Szczegóły mogą się różnić, ale ogólnie rzecz biorąc, nowoczesne procesory wielordzeniowe mają wielopoziomową hierarchiczną pamięć podręczną. Co więcej, najszybsze, ale i najmniejsze pamięci podręczne należą do poszczególnych rdzeni.

    Kiedy jeden rdzeń modyfikuje wartość w swojej pamięci podręcznej, inne rdzenie nie mogą już używać starej wartości. Wartość w pamięci podręcznej innych rdzeni musi zostać zaktualizowana. Co więcej, należy zaktualizować cała linia pamięci podręcznej, ponieważ pamięci podręczne działają na danych na poziomie wiersza.

    Zademonstrujmy ten problem za pomocą następującego kodu:

    prywatny statyczny int s_counter = nowy int;

    prywatny nieważny licznik aktualizacji (pozycja int)
    {
    for (int j = 0; j< 100000000; j++)
    {
    s_licznik = s_licznik + 3;
    }
    }


    Jeśli na mojej czterordzeniowej maszynie wywołam tę metodę z parametrami 0, 1, 2, 3 jednocześnie z czterech wątków, to czas działania wyniesie 4,3 sekundy. Ale jeśli wywołam metodę z parametrami 16, 32, 48, 64, to czas działania będzie wynosił tylko 0,28 sekundy.

    Dlaczego? W pierwszym przypadku wszystkie cztery wartości przetwarzane przez wątki w danym momencie prawdopodobnie wylądują w jednej linii pamięci podręcznej. Za każdym razem, gdy jeden rdzeń zwiększa wartość, oznacza komórki pamięci podręcznej zawierające tę wartość w innych rdzeniach jako nieprawidłowe. Po tej operacji wszystkie pozostałe jądra będą musiały ponownie buforować linię. To sprawia, że ​​mechanizm buforowania nie działa, co obniża wydajność.

    Przykład 7: Złożoność sprzętu

    Nawet teraz, gdy zasady działania pamięci podręcznej nie są dla Ciebie tajemnicą, sprzęt wciąż będzie sprawiał Ci niespodzianki. Procesory różnią się między sobą metodami optymalizacji, heurystyką i innymi subtelnościami implementacyjnymi.

    Pamięć podręczna L1 niektórych procesorów może uzyskać dostęp do dwóch komórek równolegle, jeśli należą one do różnych grup, ale jeśli należą do tej samej grupy, tylko sekwencyjnie. O ile mi wiadomo, niektórzy mogą nawet uzyskać równoległy dostęp do różnych części tej samej komórki.

    Procesory mogą zaskoczyć Cię sprytnymi optymalizacjami. Przykładowo kod z poprzedniego przykładu dotyczący fałszywego udostępniania pamięci podręcznej nie działa na moim domowym komputerze zgodnie z zamierzeniami – w najprostszych przypadkach procesor potrafi zoptymalizować pracę i ograniczyć negatywne skutki. Jeśli trochę zmodyfikujesz kod, wszystko ułoży się na swoim miejscu.

    Oto kolejny przykład dziwnych dziwactw sprzętowych:

    prywatny statyczny int A, B, C, D, E, F, G;

    prywatna statyczna nieważność Dziwność()
    {
    for (int i = 0; tj< 200000000; i++)
    {
    <какой-то код>
    }
    }


    Jeśli zamiast tego<какой-то код>Zastąp trzy różne opcje, aby uzyskać następujące wyniki:

    Zwiększanie pól A, B, C, D trwa dłużej niż zwiększanie pól A, C, E, G. Jeszcze dziwniejsze jest to, że zwiększanie pól A i C trwa dłużej niż pól A, C I E, G. Nie wiem dokładnie, jakie są tego przyczyny, ale być może są one związane z bankami pamięci ( tak, tak, ze zwykłymi trzylitrowymi bankami pamięci oszczędnościowej, a nie tym, o czym myślałeś). Jeśli masz jakieś przemyślenia na ten temat, prosimy o wypowiedzenie się w komentarzach.

    Na moim komputerze nie obserwuje się powyższego, jednak czasami występują wyjątkowo złe wyniki - najprawdopodobniej harmonogram zadań wprowadza własne „korekty”.

    Lekcja, jaką można wyciągnąć z tego przykładu, jest taka, że ​​bardzo trudno jest całkowicie przewidzieć zachowanie sprzętu. Tak, Móc dużo przewidzieć, ale trzeba stale potwierdzać swoje przewidywania poprzez pomiary i testy.

    Wniosek

    Mam nadzieję, że wszystko omówione powyżej pomogło ci zrozumieć konstrukcję pamięci podręcznej procesora. Teraz możesz zastosować tę wiedzę w praktyce, aby zoptymalizować swój kod.