Как CPU изпълнява операция, която манипулира данни, които са по-малки от размер на дума

Бях чел, че когато процесорът чете от паметта, той ще прочете размера на думата на паметта наведнъж (като 4 байта или 8 байта). Как процесорът може да постигне нещо като:

 mov     BYTE PTR [rbp-20], al

където копира само един байт данни от al в стека. (като се има предвид, че ширината на шината за данни е като 64-битова ширина) Ще бъде чудесно, ако някой може да предостави информация за това как се изпълнява на хардуерно ниво.

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

0:  b8 00 00 00 00          mov    eax,0x0

е с дължина 5 байта код (на x84) и

0:  31 c0                   xor    eax,eax

е с дължина 2 байта код, те имат различна дължина на размера.

ако контролният блок иска да извлече тези инструкции, прави ли го:

  1. извлича 8 байта байт код (може да се състои от множество инструкции) и след това изпълнява само част от тях.
  2. извличане на инструкции, които са по-малки от 8 байта (прочетете 8 байта от паметта, но други байтове ще бъдат игнорирани)
  3. инструкциите вече са подплатени (от компилатор или нещо подобно).

какво ще кажете за инструкции като:

0:  48 b8 5c 8f c2 f5 28    movabs rax,0x28f5c28f5c28f5c
7:  5c 8f 02

което надвишава размера на думата, как се обработват от процесора?


person Sayakura    schedule 04.06.2019    source източник
comment
Възможен дубликат на Може ли съвременният x86 хардуер да не съхранява нито един байт в паметта?.   -  person Peter Cordes    schedule 04.06.2019


Отговори (4)


x86 изобщо не е ориентирана към думи архитектура. Инструкциите са с променлива дължина без подравняване.

"Размер на думата" не е смислен термин на x86; някои хора може да го използват за позоваване на ширината на регистъра, но извличането/декодирането на инструкции няма нищо общо с целочислените регистри.

На практика при повечето модерни процесори x86 извличането на инструкции от L1 кеша за инструкции се извършва в подравнени 16-байтови или 32-байтови блокове за извличане. По-късните етапи на тръбопровода намират границите на инструкциите и декодират до 5 инструкции паралелно (напр. Skylake). Вижте описанието на David Kanter за Haswell за блокова диаграма на предния край показващ извличане на 16-байтова инструкция от L1i кеша.

Но имайте предвид, че модерните x86 процесори също използват декодиран uop кеш, така че не трябва да се справят с трудния за декодиране x86 машинен код за код, който се изпълнява много често (напр. в цикъл, дори голям цикъл). Работата с неподравнени инструкции с променлива дължина е значително пречка за по-старите процесори.


Вижте Може ли съвременният x86 хардуер да не съхранява нито един байт към паметта? за повече относно това как кешът абсорбира съхранява в нормални региони на паметта (MTRR и/или PAT, зададени на WB = тип памет с обратен запис).

Логиката, която ангажира съхранява от буфера за съхранение към L1 кеш на данни на съвременните процесори на Intel, обработва всеки магазин с всякаква ширина, стига да се съдържа изцяло в един 64-байтов кеш ред.

Не-x86 процесорите, които са по-ориентирани към думи (като ARM), обикновено използват четене-модифициране-запис на кеш дума (4 или 8 байта), за да обработват тесни хранилища. Вижте Има ли модерни процесори, при които съхраняването на кеширани байтове всъщност е по-бавно от хранилището на думи? Но съвременните процесори x86 изразходват транзисторите, за да направят съхраняваните кеширани байтове или неподравнените по-широки хранилища точно толкова ефективни, колкото подравнените 8-байтови хранилища в кеш памет.


предвид ширината на шината за данни е като 64 бита

Модерният x86 има контролери на паметта, вградени в процесора. Тази DDR[1234] SDRAM шина има 64 линии за данни, но една команда за четене или запис инициира пакет от 8 трансфера, прехвърляйки 64 байта данни. (Неслучайно 64 байта е размерът на реда на кеша за всички съществуващи процесори x86.)

За съхраняване в некешируем регион на паметта (т.е. ако процесорът е конфигуриран да третира този адрес като некешируем, въпреки че е подкрепен от DRAM), еднобайтово или друго тясно съхранение е възможно с помощта на сигналите за байтова маска на DQM, които казват на DRAM паметта кои от 8-те байта действително трябва да бъдат съхранени от този пакетен трансфер.

(Или ако това не се поддържа (което може да е така), контролерът на паметта може да трябва да прочете старото съдържание и да обедини, след което да съхрани целия ред. Така или иначе, 4-байтови или 8-байтови парчета са неважната единица тук. DDR пакетните трансфери могат да бъдат съкратени, но само до 32 байта от 64. Не мисля, че 8-байтовото подравнено записване всъщност е много специално на ниво DRAM. Гарантирано е да бъде "атомен" в x86 ISA обаче, дори и в некеширащи се MMIO региони.)

Съхранение в некешируем MMIO регион ще доведе до PCIe транзакция с подходящ размер, до 64 байта.


Вътре в ядрото на процесора шината между кеша за данни и изпълнителните модули може да бъде широка 32 или 64 байта. (Или 16 байта на текущия AMD). И прехвърлянето на кеш линии между L1d може L2 кеш също се извършва през 64-байтова широка шина, на Haswell и по-нови.

person Peter Cordes    schedule 04.06.2019
comment
Според това, някои DDR4 чипове може да не поддържат маски за запис. В този случай целевата 8-байтова част се чете и обединява с данните за запис. - person Hadi Brais; 04.06.2019

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

mov     BYTE PTR [rbp-20], al

Например, за да изпълни това, процесорът първо ще гарантира, че редът, съдържащ този байт, е в кеша за данни (което вероятно включва прехвърляне на един или повече блокове с размер на шина от паметта), и след това ще запише в този байт.

Инструкциите за декодиране идват от кеша за инструкции, който е оптимизиран да предава поточно данни в декодерите, така че те да могат да се справят с неподравнени инструкции, които пресичат границите на думите.

person Chris Dodd    schedule 04.06.2019
comment
когато споменахте кеша, всичко започна да има смисъл, но поради липсата на разбиране на кеша, не мога да визуализирам процеса who по ясен начин, имате ли някаква препоръка/допълнителни неща за четене на кеша на паметта? От източниците, които прочетох, те го описват накратко като банка с бърза памет, но никога не навлизат в комуникацията между други компоненти и кеша. - person Sayakura; 04.06.2019

Шината на ръба на процесора в наши дни вероятно е 64 бита. но така или иначе 16, 32, 64 и т.н. Също така дизайните могат/да варират, но нещото, за което питате е, че процесорът за четене ще издаде четене с размер на шина, така че за адрес 0x1001 ще се случи четене на 0x1000 под някаква форма (понякога контролерът на паметта или контролерът на кеша или каквото и да е от другата страна на тази шина ще бъде този, който ще премахне по-ниските битове от адреса). Следващият слой за четене в идеалния случай ще направи четене с размер на дума или автобус. Може да имате или да нямате кеш тук, няма значение по отношение на този въпрос, ако е така, тогава ако има попадение, тогава тази ширина ще бъде прочетена и изпратена обратно към процесора, при пропуск известен брой единици, обикновено много пъти ширината на шината ще се чете като кеш линия, думата/или каквато и да е единица ще бъде изпратена обратно към процесора. за четене процесорът обикновено изолира броя байтове на подшината от това четене и ги консумира, като игнорира останалите. имайте предвид, че това не е прахосничество, а точно обратното.

Записите са мястото, където е проблемът с производителността. Ако пишете неподравнена или със сигурност по-малка от пълна широчина на шината, тогава трябва да посочите на контролера на паметта валиден от невалидни битове или байтове, обикновено байтове в някаква форма. Един от начините е да имате байтова маска, така че за 32-битова шина ще имате 4 бита байтова маска, която да представлява всеки от 8-битовите байта, преминаващи през тази шина наведнъж. След това контролерът на паметта или контролерът на кеша ще трябва да извърши четене-модифициране-запис (има изключения, но в този случай просто го изпълнявайте). Така че запис на един байт в 0x1001 ще остави процесора на тази вътрешна/затворена шина с този адрес или 0x1000 като адрес, байтова маска от 0b0010 и стойността на данните под формата на 32-битово число, от което само вторият байт лента има валидни битове, другите могат да бъдат боклук или нули или каквото и да е. За вида системи, за които се задава цитат/въпрос като този, означава, че външните слоеве на паметта са достъпни в тези широки единици, байтовете са възможни, но се предполага, че не се използват. Самият кеш вероятно е съставен от широки sram, 32 бита би било разумно в този случай, така че за да запишете еднобайтово местоположение в sram на кеша, изисква четене на тези 32 бита, модификация на 8 бита, които се променят и след това напишете местоположението на sram. това няма абсолютно нищо общо с преминаването на запис в кеша или обратен запис или каквото и да е напълно без значение. това е вътрешната работа на sram, заровена дълбоко в кеша. той губи недвижимо пространство на чипа, за да изгради кеш от 8-битови широки памети, също така умножава броя на сигналите, което кара част от това загубено пространство да ги маршрутизира, плюс логика, за да ги контролира, всички пропилени. Така че ще се използва по-широка памет за донякъде разумен дизайн. Възможно е повече от 39 или 40 бита ширина, за да има малко ecc на тези sram.

подобно, ако не е същото, ако нямате кеш или кешът не е активиран. можете да изтеглите axi документация от arm можете да потърсите някои други известни автобуси. вътрешната работа на x86, въпреки че там, където тази дейност би била видима, наистина няма да има работа да бъде документирана извън intel или amd.

x86 има значителни разходи, за да се справи с набора от инструкции, така че не трябва да виждате удар на производителността от тези записи. други архитектури с по-малко режийни разходи можете/ще видите тези хитове на производителността.

person old_timer    schedule 04.06.2019

Кешовете се обсъждат в повечето книги за компютърна архитектура. На нивото на зададения въпрос „Дигитален дизайн и компютърна архитектура“ от Harris & Harris или на това ниво може да е достатъчно.

Вероятно търсите блокова диаграма като тази, която прилагам по-долу, за да разберете бързо конвейера и да продължите напред. Не знам за книга, която да прави това. Отне ми ‹ 30 минути, за да нарисувам това (& строго за забавление) - вземете го за това, което си струва. Но ако откриете грешки или имате други корекции, публикувайте ги тук за бъдещи посетители на тази страница.

Къде е кешът!

person ShankarSwamy    schedule 06.06.2019