Процесорен кеш

от Уикипедия, свободната енциклопедия

Процесорен кеш (CPU кеш) е кешпамет, използвана, за да се намали времето за достъп от страна на централния процесор до информацията в RAM паметта. Повечето компютърни процесори имат няколко независими една от друга кешпамети.

Общ преглед[редактиране | редактиране на кода]

Когато процесорът трябва да чете или записва данни в RAM паметта, първо проверява дали тези данни не съществуват в кеша на централния процесор. Ако те съществуват, процесорът ги чете от там, а ако не е така – чете ги от RAM и ги записва в кеша. Четенето от кешпаметта е много по-бързо от четенето от RAM паметта.

Повечето модерни десктопи и сървърни процесори имат поне три независими кешпамети: инструкционен кеш, кеш за данни и кеш буфер за транслациите.

Вписвания в кеша[редактиране | редактиране на кода]

Данните са пренасят между паметта и кеша в блокове с фиксиран размер, наречени кеш линии. Вписването е осъществено, когато кеш линиите се трансферират в кеш паметта.

Производителност[редактиране | редактиране на кода]

Пропуските при четене забавят изпълнението защото се изисква данните да бъдат трансферирани от паметта, която е много по-бавна от кеш паметта.

Структура за вписванията в кеша[редактиране | редактиране на кода]

Кешовите вписвания имат следната структура:

таг блок с данни битови флагове

Блокът с данни съдържа данни извлечени от RAM паметта. Тагът съсдържа адреса на данните в RAM паметта.

Размерът на кеша е количеството на данните които кешът може да съхрани от RAM паметта. Размерът може да бъде определен, като броят на битовете запазен във всеки блок от данни се умножи по броя на блоковете.

Ефективният адрес на паметта е разделен на таг, индекс и отклонение на блока. Дължината на тага в битове е равна на:

дължина_на_адрес – дължина_на_индекс – дължина_на_отклонение_на_блоковете
таг индекс отклонение на блока

Индексът показва в кой кешов ред са данните. Дължината на инекса е 2, къдете b е броят на битовете в даден блок. Тагът съдържа най-значимите частици от адреса, които са сверени с текущия ред, за да се провери дали това са нужните ни данни или са други.

Превод на адреса[редактиране | редактиране на кода]

Повечето процесори с общо предназначение използват виртуална памет. Всяка програма работеща на компютъра, вижда своето обобщено адресно пространство, което съдържа код и данни само за тази програма, или за всички програми, споделящи общо виртуално пространство.

Виртуалната памет изисква процесорът да „преведе“ виртуалния адрес, генериран от програмата, във физически адрес от RAM паметта. Частта от процесора, извършваща тази дейност, е позната като MNU, който може да извърши тези преводи и да ги съхрани в TLB.

Някои първични виртуални памети са били бавни, понеже са изисквали повече време за достъп. Без кеш това намалява скоростта на машината на половина.

Кеш йерархия в модерните процесори[редактиране | редактиране на кода]

Модерните процесори имат множество взаимодействащи кешове на чиповете.

Операцията на специфичния кеш може да бъде определен по:

  • размера на кеша
  • размера на кеш блока
  • броя на блокове в сет
  • поведението на заместване на кеш сета
  • поведението на записването на кеша

Всички кеш блокове в определен кеш са с еднакъв размер и имат еднаква асоциативност, обикновено кешовете от „по-ниско ниво“ (като L1 кеш) имат по-малък размер, по-малко блокове, и по-малък брой блокове в сет, докато кешовете от „по-високо ниво“ (като L3 кеш) имат по-голям размер, по-големи блокове, и по-голям брой блокове в сет.

Специализирани кешове[редактиране | редактиране на кода]

Поточните процесори използват паметта от много точки в потока: извикване на инструкции, виртуален към физически превод и извикване на данни. Естествения дизайн е да се използват различни физически кешове за всяка от тези точки, за да няма нужда никои от физическите ресурси да бъдат планирани да обслужват две точки в потока. Така потока естествено има поне три различни кешове (инструкции, кеш буфер за транслациите, и данни), като всеки е специализиран за неговата определена роля.

Жертвов кеш[редактиране | редактиране на кода]

Жертвов кеш е кеш, който се използва да държи блокове изгонени от процесорния кеш при заместване. Жертвовия кеш седи между главния кеш и неговия път на зареждане, и държи само блокове, които са изгонени от главния кеш. Жертвовия кеш по принцип е напълно асоциативен, и е предназначен да намалява броя на конфликтни инциденти. Доста често използвани програми не изискват асоциативно планиране за всеки отделен достъп. Всъщност само малка част от достъпите в паметта на програмата изискват висока асоциативност.

Проследяващ кеш[редактиране | редактиране на кода]

Един от по-екстремните примери за специализиран кеш е проследяващия кеш намеращ се в Intel Pentium 4 микропроцесорите. Проследяващия кеш е механизъм за увеличаване на честотната лента за изкикване на функции и намаляване на консумацията на ток (в случая на Pentium 4) като запазва следи от инструкциите които вече са били извикани и декодирани.

Проследяващият кеш запазва инструкции или след като те са декодирани, или след като те се „пенсионират“. По принцип, инструкциите се добавят за да следят кешове в групи представящи или индивидуални прости блокове или динамични следи на инструкции. Една динамична следа съдържа само инструкции резултатите на които всъщност се използват, и елиминира инструкции след взети клонове (защото те няма да се изпълнят); динамична следа може да бъде конкатенация на множество просто блокове. Това позволява на участъка на процесора, който извиква инструкциите да извиква няколко прости блокове, без да трябва да се притеснява за клонове в потока на изпълнение.

Кешове на много нива[редактиране | редактиране на кода]

Друг проблем е фундаментален компромис между латентност и ударна скорост. По-големи кешове имат по-добра ударна скорост, но повече латентност. За да адресират този компромис, много компютри използват няколко нива от кеш, като малките бързи кешове са подкрепени от по-големи, но по-бавни кешове. Кешовете на няколко нива по принцип действат като проверяват най-бързия, level 1 (L1) кеш първо; ако то удари, процесора продължава на висока скорост. Ако по-малкият кеш не удари, следващия най-бърз кеш, level 2 (L2) се проверява, и така нататък, преди да се провери външната памет.

С увеличаването на разликата в латентност между главната памет и най-бързия кеш, някои процесори започнаха да използват до 3 нива кеш за самия чип. Дизайни които са чувствителни към цена използват това за да издърпат целата йерархия на кеша на самия чип, но след 2010 някои от най-високо производителните дизайни се върнаха към имайки големи кешове извън самия чип – често имплементирани като eDRAM и монтирани на многочипов модул – като четвърто ниво кеш.

Ползите от L3 и L4 кеша зависят от начина, по който апликацията борави с данните. Примери за продукти, които използват L3 и L4 кеш, включват следните:

    • Alpha 21164 (1995) има 1 до 64 MB L3 кеш извън чипа.
    • IBM POWER4 (2001) има L3 извън чипа от размери 32 MB на процесор, споделен с няколко процесора.
    • Itanium 2 (2003) има 6 MB обединен level 3 (L3) кеш на чипа; Itanium 2 (2003) MX 2 модула използва два Itanium 2 процесора със споделен 64 MB L4 кеш на многочипов модул който е съвместим пиново с Madison процесор.
    • Intel's Xeon MP продукт с кодово име „Tulsa“ (2006) има 16 MB L3 кеш на чипа споделен с две процесорни ядра.
    • AMD Phenom II (2008) има до 6 MB обединен L3 на чипа.
    • Intel Core i7 (2008) има 8 MB обединен L3 кеш на чипа който е обхващащ, споделен с всички ядра.
    • Intel Haswell процесори с интегрирани Intel Iris Pro графики имат 128 MB eDRAM памет изпълнявайки ролята на L4 cache.

Многоядрени чипове[редактиране | редактиране на кода]

Когато се имат предвид многоядрените чипове, има разлика дали кешовете са споделени или локални за всяко ядро. Реализирането на споделен кеш безспорно изисква повече електрически връзки и сложност. Но когато има общ кеш за всеки чип, вместо по един на всяко ядро, е необходимо доста по-малко пространство, следователно може да се побере по-голям кеш.

Обикновено споделянето на L1 кеш е нежелано, защото в резултат от увеличената латентност всяко ядро ще върви доста по-бавно от един едноядрен чип. От друга страна, за най-високото ниво, глобален кеш е желан поради няколко причини. Например, осемядрен чип с три нива кеш може да включи L1 кеш за всяко ядро, един междинен L2 кеш за всяка двойка ядра, и един L3 кеш, споделен с всичките ядра.

Споделен кеш от най-високо ниво, който се извиква преди четенето на паметта, обикновено се нарича last level cache (LLC) или последно ниво кеш. Още техники се използват за увеличаването на нивото на паралелизъм когато LLC е споделен между няколко ядра, включително и независимо адресиране на определени обхвати от адреси на паметта.

Асоциативност[редактиране | редактиране на кода]

Възстановителната полица взима решение къде в кеша ще отиде копие от даден запис от основната памет. Ако възстановителната полица е свободна да избере кое влизане в кеша да съдържа копието, кешът се нарича „fully associative“ (напълно асоциативен). В другия случай, ако с всяко влизане в основната памет, може да се отиде само на едно място в кеша, кешът е“direct mapped”(директно свързан). Много кешове постигат компромисен вариант, при който с всяко влизане в основната памет може да се получи достъп до едно от N местата в кеша. Описани са като „N-way associative“. Например кеш ниво-1 данни в AMD Athlon e „two-way set associative“, което означава, че всяко конкретно място в основната памет може да бъде кеширано в едно от двете места в кеша данни на ниво-1.

Асоциативността е компромис. Ако има десет места, на които възстановителната полица може да е оставила място в паметта, тогава, за да разберем дали това място е в кеша, десет кеш записа трябва да бъдат проверени. Проверката на повече места отнема повече мощност и място за чипове и потенциално повече време. От друга страна, кешовете с повече асоциативност страдат от по-малко загуби. Централният процесор губи по-малко време, четейки от основната памет. Асоциативностите увеличени над четири пъти оказват много по-малко влияние върху успеваемостта и обикновено се правят поради други причини.

С цел от по-лошо, но просто, към по-добро, но сложно:

  • директно свързан кеш – добър в най-добрия случай във времето, но несъвършен в най-лошия случай
  • двупосочно зададен асоциативен кеш
  • двупосочно изкривен асоциативен кеш
  • четирипосочно зададен асоциативен кеш
  • eight-way зададен асоциативен кеш – общ избор за по-късните реализации
  • 12-way зададен асоциативен кеш, подобен на eight-way
  • напълно асоциативен кеш – практически само за малък брой записи

Директно свързан кеш[редактиране | редактиране на кода]

В тази кеш организация, на всяко място в основната памет може да отиде само един запис в кеша. Ето защо директно свързания кеш може да бъде наричан още „one-way set associative“ кеш. Няма право на избор от съдържанието на кой входен кеш да вземе. Това означава, че ако две връзки сочат към един и същ ход, те могат непрекъснато да се пращат една на друга. Въпреки това, директно свързаният кеш трябва да бъде много по-голям от асоциативния, за да се получава подобна производителност и е по-непредсказуем. Нека х бъде номер на блок в кеша, у бъде номер на блок от паметта и n е номера на блоковете в кеша, тогава свързването се извършва с помощта на уравнението x = y mod n.

Двупосочно зададен асоциативен кеш[редактиране | редактиране на кода]

Ако всяко място в основната памет може да бъде кеширано в едно от двете места в кеш паметта, един логичен въпрос е: Кое едно от двете? Най-простата и най-често използваната схема е да се използват най-незначителните битове на мястото на индекс от паметта и да има два записа за всеки индекс. Едно от предимствата на тази схема е, че таговете съхранени в кеш паметта не трябва да включват тази част от адреса на основната памет, която се подразбира от индекса на паметта на кеша. Докато кеш таговете са няколко бита, те се нуждаят от по-малко транзистори, заемат по-малко място на процесорната платка или върхуу чипа на микропроцесора и могат да бъдат прочитани и сравнявани по-бързо. Също така LRU (Least Recently Used – най-малко ползван напоследък) са особено прости, тъй като само един бит трябва да се съхранява за всяка двойка.

Спекулативни изпълнения[редактиране | редактиране на кода]

Едно от предимствата на директно свързания кеш е, че позволява лесно и бързо предположение. След като адресът е изчислен, кешовият индекс, който може да има копие на това място в паметта е известен. Този входен кеш може да бъде прочетен и процесорът може да продължи да работи с тези данни, преди да е приключила проверката, че тагът действително съответства на искания адрес. Идеята, процесорът да използва кеширани данни, преди да завърши съвпадението на таговете е, че може да се прилага като асоциативен кеш. Една подгрупа на тага, наречена „hint“, може да бъде използвана, за да се избере само един от възможните кеш записи, отговарящи на зададения адрес. Текстът, избран от „hint“-а може след това да бъде използван едновременно с проверка на пълния таг. Техниката „hint“ работи най-добре, когато се използва в контекста на адресен превод, както е обяснено по-долу. 

Двупосочно изкривен асоциативен кеш[редактиране | редактиране на кода]

Други предложени схеми, като изкривена кеш, където индексът за way 0 е директен, както по-горе, но индексът за way 1 се формира с хеш функция. Една добра хеш функция има свойството, адресите, които са в противоречие с директно свързване, не са склонни да са в конфликт, когато са свързани с хеш функция. Така е по-малко вероятно, че една програма ще страда от неочаквано голям брой конфликтни пропуска поради модела за достъп. Недостатък е допълнителната латентност от изчислителната хеш функция. Освен това, когато дойде време да се зареди нов ред и да се премахне стар, може да е трудно да се определи кой съществуващ ред е бил използван, защото новият ред е в противоречие с данните на различните индекси. LRU проследяване за не-изкривени кешове обикновено се прави по зададена база. Независимо от това, изкривените-асоциативни кешове имат значителни предимства пред конвенционално поставените-асоциативни такива.

Псевдо-асоциативен кеш[редактиране | редактиране на кода]

Един истински набор-асоциативен кеш тества всички възможни начини едновременно, като се използва нещо подобно на съдържание на адресируема памет. Псевдо-асоциативният кеш тества всеки възможен начин един по един.“Hash-rehash“ кеш и „column-associative“ кеш са примери за псевдоасоциативен кеш. В общия случай на намиране на съвпадение при тестване по първия начин, псевдоасоциативната кеш е бърза колкото директно свързаната кеш.