Власна платформа ч0.1 Теорія про процесорах

Введення
Здрастуй, Світ!
Сьогодні у нас серія статтею для людей з середніми знаннями про роботу процесора в якій ми будемо розбиратися з процесорними архітектурами (у мене спелл чекер лається на слово Архітектурами/Архітектур, сподіваюся я пишу слово правильно), створювати власну архітектуру процесора і багато іншого.
4004
Приймаються будь-які зауваження! :)

Трохи про архітектуру процесора.
Історично склалося, що існують багато процесорів і багато архітектур. Але багато архітектури мають схожості. Спеціально для цього з'явилися "Групи" архітектур типу RISC, CISC, MISC, OISC (URISC). Крім того вони можуть мати різні архітектури адресації пам'яті (фон Неймана, Гарвард). У кожного процесора є своя архітектура. Наприклад більшість сучасних архітектур це RISC (ARM, MIPS, OpenRISC, RISC-V, AVR, PIC** і т. д.), але є архітектури, які виграли просто за рахунок інших факторів (Наприклад зручність/ціна/популярність/etc) Серед яких x86, x86-64 (Варто відзначити, що x86-x64 і x86, в останніх процесорах використовують мікрокод і всередині них варто RISC ядро), M68K. У чому ж їх відмінність?
RISC
Reduced Instruction Set Computer — Архітектура з зменшеним часом виконання інструкцій (розшифровка RISC можна подумати, що це зменшене кількість інструкцій, але це не так). Дане напрямку розвинулося у підсумку після того, як виявилося, що більшість компіляторів того часу не використовували всі інструкції і розробники процесорів вирішили отримати більше продуктивності використовую Конвеєри. В цілому RISC є золотою серединою між усіма архітектурами.
Яскраві приклади даної архітектури: ARM, MIPS, OpenRISC, RISC-V
TTA
Що таке TTA? ТТА це Архітектура на основі лише однієї інструкції переміщення з однієї адреси пам'яті в іншу. Даний варіант ускладнює роботу компілятора зате дає велику продуктивність. У даної архітектури є єдиний недолік: Сильна залежність від шини даних. Саме це і стало причиною її меншої популярності. Треба відзначити, що TTA є різновидом OISC.
Яскраві приклади: MOVE Project
OISC (URISC)?
One Instruction Set Computer — Архітектура з єдиною інструкцією. Наприклад SUBLEQ. Такі архітектури часто мають вигляд: Зробити дію і в залежності від результату зробити стрибок або продовжити виконання. Найчастіше її реалізація досить проста, продуктивність маленька, при цьому знову обмеження шиною даних.
Яскраві приклади: BitBitJump, ByteByteJump, SUBLEQ тисячі їх!
CISC
CISC — Complex Instruction Set Computer — її особливість в збільшених кількостях дій за такт. Таким чином можна було теоретично збільшити продуктивність програм за рахунок збільшення складності компілятора. Але за фактом у CISC погано були реалізовані деякі інструкції т. к. вони рідко використовувалися, і підвищення продуктивності не було досягнуто. Особливістю цієї групи є ще ВЕЛИЧЕЗНА Різниця між архітектурами. І незважаючи на назви були архітектури з маленькою кількістю інструкцій.
Яскраві приклади: x86, M68K
Адресація пам'яті
Архітектура фон Неймана
Von Neuman Wiki
Особливістю таких архітектур була загальна шина даних і інструкцій. Більшість сучасних архітектур це програмний фон Нейман, однак ніхто не забороняє робити апаратний Гарвард. У даній архітектури великим недоліком є велика залежності продуктивності процесора від шини. (Що обмежує загальну продуктивність процесора).
Архітектура гарварду
Harvard
Особливість цієї архітектури є окрема шина даних і інструкцій. Дає велику продуктивність чим фон Нейман за рахунок можливості за один такт використовувати обидві шини (читати шини інструкцій і одночасно записувати в шинну даних), але ускладнює архітектуру і має деякі обмеження. В основному використовується в мікроконтролерах.
Особливості процесорів
Конвеєри
Що таке конвеєри? Якщо сказати дуже дурним язиком це кілька паралельних дій за один такт. Це дуже грубо, але при цьому відображає суть. Конвеєри за рахунок ускладнення архітектури дозволяють підняти продуктивність. Наприклад конвеєр дозволяє прочитати інструкцію, виконати попередню і записати в шину даних одночасно. pipeline
На картинці більш зрозуміло, не правда?
IF — отримання інструкції,
ID — розшифровка інструкції,
EX — виконання,
MEM — доступ до пам'яті,
WB — запис в регістр.
Ніби все просто? А ось і ні! Проблема в тому що наприклад стрибок (jmp/branch/etc) змушують конвеєр почати виконання (отримання слід. інструкції) заново таким чином викликаючи затримку в 2-4 такти перед виконання наступної інструкції.
Розширення існуючих архітектур
Досить популярною технікою є додавання у вже існуючу архітектуру більше інструкцій через розширення. Яскравим прикладом є SSE під x86. Цим грішить ARM і MIPS і практично все. Чому? Тому що не можна створити унивирсальную архітектуру.
Іншим варіантом є використання інших архітектур для зменшення розміру інструкцій.
Яскравий приклад: ARM зі своїм Thumb, MIPS з MIPS16.
Техніки застосовуються в GPU
У відеокартах часто зустрічається багато ядер і з-за цієї особливості з'явилася потреба в додаткових рішень. Якщо конвеєри можна зустріти навіть в мікроконтролерах рішення використовуваних в GPU зустрічаються рідко. Наприклад Masked Execution (Зустрічається в інструкціях ARM, але не Thumb-I/II). Ще є інші особливість: це ухил у бік Floating Number (Числа з плаваючою комою), Зменшення продуктивності на противагу більшої кількості ядер і т. д.
Masked Execution
Цей режим відрізняється від класичного тим, що інструкції виконуються послідовно без використання стрибків. В інструкції зберігається деяка кількість інформації про те, за яких умов ця інструкція буде виконана і якщо умова не дотримана то інструкція пропускається.
Але Навіщо?
Відповідь проста! Що б не навантажувати шину інструкцій. Наприклад у відеокартах можна завантажити тисячі ядер однією інструкцією. А якби використовувалася система стрибків то довелося б для кожного ядра чекати інструкцію з повільної пам'яті. Кеш частково вирішує проблему, але все ще не вирішує проблему повністю.
Інше
Тут ми будемо описувати декілька технік, що використовуються в центральний процесорах і мікроконтролерах.
Переривання
Interrupts
Переривання це техніка при якій виконується в даний момент код призупиняється для виконання якоїсь іншої задачі при будь-яких умовах. Наприклад при доступі в неіснуючий ділянка пам'яті викликається HardFault або MemoryFault переривання або виключення. Або наприклад якщо таймер відрахував до нуля. Це дозволяє не чекати поки потрібно чекати якусь подію.
Які недоліки? Виклик переривання це кілька тактів простою і кілька при повернення з переривання. Так само кілька інструкцій на початку коду буде зайнято інструкціями для Таблиці переривань.
Exception (виключення)
Але крім переривань ще існують винятків які виникають наприклад, ділення на нуль. Найчастіше її поєднують із перериваннями і системними викликами, як наприклад в MIPS. Виключення не завжди присутні в процесорі наприклад як в AVR або молодших PIC
Системні виклики
Системні виклики використовується в Операційних системах для того, щоб програми могли спілкуватися з операційною системою наприклад просити ОС прочитати файл. Дуже схоже на переривання. Аналогічно винятків не завжди присутні в процесорі
Контролери доступу в пам'ять і інші методи стримування програм
Тут описуються методи заборони доступу додатків до апаратури безпосередньо.
Привілейований режим
Це режим, в якому стартує процесор. В такому режимі програма або ОС мають повний доступ до пам'яті в обхід MMU/MPU. Всі програми запускаються в непривілейованому режимі під уникнення прямого доступу до апаратних підсистем програм для цього не призначених. Наприклад шкідливим програмам. У Windows її часто називають Ring-0 а в *nix системним. Не варто плутати РУТ і Привілейований режим бо в руті ви все ще не можете мати прямий доступ до апаратури (можна завантажити системний модуль який дозволить це зробити, але про це трохи пізніше :)
MPU MMU
MMU
MPU MMU використовується в сучасних системах щоб ізолювати кілька додатків. АЛЕ якщо MMU дозволяє "пересунути" пам'ять то MPU дозволяє блокувати доступ до пам'яті/запуск коду в пам'яті.
PIC (PIE)
Що таке PIE? (PIC не використовую для уникнення плутанини з МК PIC)
PIE це технік завдяки якому компілятор генерує код який буде працювати в будь-якому місці пам'яті. Це техніка в поєднанні з MPU дозволяє компілювати високі мови програмування які будуть працювати і з MPU.
SIMD
Популярна техніка SIMD використовується для того що б за один такт виконувати кілька дій над кількома регістрами. Іноді бувають у якості доповнень до основної архітектурі наприклад, MIPS, ARM зі своїми NEON/VFP/etc, x86 зі своїм SSE2.
Reposition for Optimization
Це техніка використовується для того що б оптимізувати код, який генерує компілятор що б збільшити продуктивність процесора за допомогою пересортировки інструкцій. Це дозволяє використовувати конвеєр на повну.
Status register
Status
Що таке регістр статусу? Це регістр який зберігає стан процесора. Наприклад знаходиться процесор в привілейованому режимі, чим закінчилася операція останнього порівняння. Використовується в зв'язці з Masked Execution. Деякі розробники спеціально виключають регістр статусу бо вона може бути вузьким місцем надійшли в MIPS.
mov vs $0 reg
В MIPS немає окремої інструкції завантаження константи в пам'ять. Але є інструкція addi і ori яка дозволяє в зв'язці з нульовим регістром ($0) емулювати роботу завантаження константи в регістр. А в інших архітектурах вона присутня. Я підняв цю тему, тому що вона знадобиться нам у статтях з практикою.
Rd, Rs vs Rd, rs, rm
Йдуть безліч суперечок щодо того, скільки повинно бути операндів в арифметичних інструкціях. Наприклад в MIPS використовується варіант з 3-ма регістрами. 2 операнда, 1 регістр запису. З іншого боку використання двох операндів дозволяє скоротити код за рахунок зменшення розміру інструкції. Приклад поєднання є MIPS16 в MIPS і Thumb-I/II ARM. У плані продуктивності вони практично ідентичні (Якщо виключати розмір інструкції як фактор).
Endianness
Endianness
Порядок байт. Можливо, вам знайомі Вирази Big-Endian і Little-Endian. Вони описують порядок байт в інструкціях/в регістрах/пам'яті/etc. Тут думаю все просто :). Є процесори які поєднують режими. Як наприклад MIPS. Або які використовують одну систему команд але мають різний порядок байт. Як приклад ARM.
Бітність процесора
І так що таке бітність процесора? Багато вважають, що це бітність шини даних. Але це не так. Чому? У ранні переоды мікроконтролерів і мікропроцесорів шина могла бути, наприклад, 4-х бітної але передавала пакетами по 8 біт. Для програми здавалося, що це 8-бітний режим, але це була ілюзія. Як і зараз. Наприклад ARM SoC-ах часто застосовують 128-бітну шину даних або інструкцій.
128/64/32
Співпроцесори
Що таке співпроцесори? Співпроцесори є елементами процесора або зовнішньої мікросхемою, що дозволяють виконувати інструкції який занадто громіздкі для основної частини процесора. Як яскравий приклад співпроцесори в MIPS для множення та ділення. Або наприклад 387 для 80386 який надавав підтримку чисел з плаваючою комою. А в MIPS співпроцесорів було багато і вони виконували свої ролі. Наприклад були контролери переривань/винятки/системних викликів. Часто співпроцесори мають власні інструкції і на системах де цих інструкцій немає (Приклад ARM) Емулюють її через Trap-и (пастки?). Незважаючи на костыльность, і маленьку продуктивність вони часто є єдиним вибором в мікроконтролерах.
Атомарність операцій
Атомартность операцій забезпечує потоко-незалежне виконання за рахунок інструкцій який виконують кілька операцій за один Псевдо такт.
Варіант іншого рішення атомарність переферії. Наприклад для установки ніжки в STM32 у високе і низьке стан використовується різні регістри, що дозволяє мати атомарність на рівні переферії.
Кеш
Cache
Ви навярника чули про L1, L2, L3 і регістрах. Якщо коротко процесор аналізує частину коду, що б передбачити стрибки і доступ в пам'ять і завчасно просить кеш отримати ці дані з пам'яті. Кеш часто буває прозорим для програми, але бувають і винятки з цього правила. Наприклад, у Програмних ядрах в ПЛІС використовується програмний кеш.
ви скінчено чули про таку річ, як Cache Miss або промах з кешу. Це операція яка не була предустмотренна процесорам або процесор не встиг закешувати цю частину пам'яті. Що досить часто є проблемою уповільнення доступу до пам'яті. Промах проходить непомітно для програми, але не залишається не помітними осідання в продуктивності. Так само перемикання контекстів наприклад при перериваннях теж змушує страждати кеш бо невеликий код збиває конвеєр і кеш для власних потреб.
Shadow Registers
У сучасних процесорах часто використовується техніка тіньових регістрів. Які дозволяють перемикатися між перериваннями і користувальницьким кодом практично без затримок пов'язаних із збереженням регістрів.
Stack
Stack
Стек? Я бачив Стек .NET і Java! Що ж. Ви частково праві. Стек існує, але він ніколи не був апаратным в більшості процесорах. Наприклад в MIPS його просто немає. Запитаєте ЯК ТАК?! Відповідь проста. Стек це просто доступ до пам'яті яку не потрібно резервувати (дуже грубе визначення). Стек використовується для виклику функцій, передачі аргументів, збереження регістрів для того щоб відновити їх після виконання функції і т. д.
Запитаєте тоді що таке хіп (Heap)? Хіп це пам'ять розміром набагато більше ніж стік (Стік зазвичай, ~1MB). У хіпі зберігатися всі глобальне. Наприклад всі покажчики отримані з допомогою Malloc вказують на частину хіпа. А покажчики зберігаються в стеці або в регістрах. З допомогою інструкцій завантаження даних щодо регістра можна прискорити роботу стека і інших доступів до пам'яті за типом стека оскільки не потрібно постійно використовувати операції PUSH/POP, INC/DEC або ADDI, SUBI (додати константу) що б отримати дані глибше по стеку, а можна просто використовувати доступ щодо стека з від'ємним зміщенням.
Регістри
Регістри
Не буду описувати регістри занадто докладно. Це ми торкнемося в практичній статті.
У x86 регістрів досить мало. В MIPS використовується збільшену кількість регістрів а саме 31 ($0 має значення завжди дорівнює нулю). В процесорі університету берклі використовувалися регістрові вікна, які жорсткі обмежували вкладення, при цьому мали більшу продуктивності. А в інших (наприклад AVR) обмежили використання регістрів (наприклад три 16 бітних, які можна трактувати, як шість восьмибітних. перші 16, які недоступні при деяких операціях). Я вважаю, що кращий метод був обраний MIPS-му. Це моє суто особиста думка.
Вирівнювання
Що таке вирівнювання? Поїду-но я це питання вам :)
Кінець
Це кінець першої глави нульовою частини. Вся серія буде крутитися навколо теми створення власного процесора. Власної операційної системи. Власного асемблера. Власного компілятор і багато чого іншого :)
Нульові частини будуть присвячені теорії.
Я сумніваюся що доведу всю серію до переможного кінця, але спроба не тортури! :)
UPD: Перша спроба оформити статтю картинками :)
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.