Теоретична мінімальна кількість регістрів для сучасного комп’ютера?


10

Я взяв курс на компілятори в моєму бакалаврському навчанні, в якому ми написали компілятор, який збирає вихідні програми на іграшці, схожі на мову Ява, на мову складання іграшок (для якої у нас був перекладач). У проекті ми зробили кілька припущень щодо цільової машини, тісно пов’язаної з "справжніми" власними виконуваними файлами, включаючи:

  • стек часу виконання, відстежуваний за допомогою спеціального реєстру вказівника стека ("SP")
  • купа для динамічного розподілу об'єктів, відстежена за допомогою спеціалізованого реєстру вказівника купи ("HP")
  • спеціальний реєстр лічильників програм ("ПК")
  • цільова машина має 16 регістрів
  • Операції над даними (на відміну від, наприклад, стрибків) - це операції "реєстрація до реєстрації"

Коли ми потрапили до підрозділу з використання розподілу реєстру в якості оптимізації, я змусив мене задуматися: Яка теоретична мінімальна кількість регістрів для такої машини? Ви можете переконатися, що в нашому компіляторі ми використовували п'ять регістрів (SP, HP, PC, плюс два для використання як сховище для бінарних операцій). Хоча для оптимізацій, таких як розподіл реєстрів, звичайно, можна використовувати більше регістрів, чи існує спосіб подолати меншу кількість, зберігаючи структури, такі як стек і купа? Я вважаю, що для адресації реєстру (операцій з реєстрацією в реєстрацію) нам потрібно принаймні два регістри, але чи потрібно нам більше двох?


"Куча покажчик" здається дивною ідеєю. Оскільки всупереч стеку, купа не є LIFO і не зводиться до семантики push / pop. Ви повинні швидше бачити динамічне розподіл пам’яті як дзвінки в програму «malloc / free».
Ів Дауст

Відповіді:


14

Якщо ви дозволяєте прямий доступ до пам'яті за адресою пам'яті, вам не потрібні "регістри", оскільки ви можете використовувати місця пам'яті. Наприклад, пам'ять у розташуванні 0 може бути лічильником програми, у місці 1 ми маємо покажчик стека тощо. Але це є обманом.

Отже, щоб не допустити до обману, припустимо, що немає прямого доступу до пам'яті, оскільки ми могли використовувати фіксовані місця пам'яті як регістри. Тоді ми можемо відійти від двох регістрів, лічильника програми та вказівника стека, як пояснено у статті Вікіпедії про стекових машинах . До стека можна отримати лише вказівник стека, а програма доступна лише через лічильник програм.

Інша можливість - використовувати лічильні машини. Машина з двома прилавками - Тьюрінг завершена, тобто вона може обчислити все, що може машина Тьюрінга. Це знову чудово пояснено у статті Вікіпедії про лічильні машини .


Дякую за відповідь! У статті про верстатні машини згадується, що машина здатна здійснювати прямий доступ до пам'яті (виконувати операції над найвищими елементами стека і відштовхувати результат назад), так що це все-таки обман, правда? Щодо лічильної машини, я прочитав цю статтю. Я також прочитав подібний доказ TC 2-CM, але обидва фактично передбачають зберігання всієї ОЗУ в двох регістрах, що мені здається навіть більше схожим на обман.
BlueBomber

Ну, в якийсь момент це вже не обман. Операції стеку не є обманом, якщо вони забороняють прямий доступ до фіксованого місця в пам'яті. Добре вміти, скажімо, повертати три найвищих елемента стека. У будь-якому випадку ваше запитання дещо дивне, тому воно не платить за нав'язливість щодо того, що є, і не обман.
Андрій Бауер

Ще раз дякую за відповідь. У будь-який час, коли тема стосується теоретичних меж, обман є ще менш прийнятним! Це не означає, що це не повчально. Справа, коли це не обман, це коли, мабуть, немає обману, я думаю. Я знайшов вашу первинну відповідь інформативною, але проблема полягає в тому, що наша модель перекриває всі моделі машини Тюрінга, Лічильника і Стек машини, і враховуючи наші припущення (включаючи кінцево багато кінцевих регістрів і відсутність прямого доступу до пам'яті), чи можемо ми отримати маючи лише два регістри?
BlueBomber

1
Я вважаю це питання дивним, оскільки важко закріпити такі поняття, як процесор, реєстрація, доступ до пам'яті тощо, але вони потрібні для того, щоб можна було щось довести. Таким чином, кінцевим результатом буде те, що все, що ви доведете, легко довести, але це дуже залежить від того, як ви формалізуєте питання (яке ваше теоретичне поняття "процесор", "зареєструвати", "пам'ять" тощо).
Андрій Бауер

1
Підручник із компілятора не дозволяє нам доводити багато, принаймні, не в математичному сенсі слова "довести". Вам потрібно пройти ще крок далі, щоб формалізувати обладнання, щоб отримати щось, що дозволить довести . Так чи інакше, ми розщеплюємо волоски, і я вже дав вам найкращу відповідь.
Андрій Бауер

1

Архітектура PIC, яка була введена General Instruments в 1970-х роках і використовується донині, мала такі регістри:

W register (not addressible)
01    Timer/Counter
02    Program Counter
03    Status
04    File-Select Register
05-07 One register for each I/O port
08-1F General-purpose registers/"memory"

Типова інструкція буде читати регістр, проводити обчислення, використовуючи значення read та W, а потім зберігати результат обчислення або W, або реєстр, який був прочитаний. Одне з доступних обчислень дає "прочитане значення, ігноруючи W"; інша - "взяти W, ігноруючи прочитане значення". Для NOP, а також для різноманітних спеціальних інструкцій використовуються бітові структури, які відповідатимуть "читати XX, потім приймати W, ігноруючи прочитане значення та зберігаючи результат у W".

Щоб дозволити обчислення адрес, блок виконання процесора буде стежити за інструкціями, що кодують адресу 00, і замінить вміст Реєстру вибору файлів на адресу.

Хоча необхідність подачі всіх значень через регістр W може бути вузьким місцем, архітектура PIC має більший робочий набір, ніж інші архітектури, використовуючи однакове слово інструкції. На PIC16C54 (як і раніше зроблено, і дуже схожа на PIC 1970-х) інструкції мають 12 біт. На багатьох інших частинах 16Cxx або 16Fxx інструкції мають 14 біт і можуть безпосередньо отримати доступ до 128-байтного адресного простору. Якщо робочий набір програми добре співпадає з робочим набором наборів інструкцій, виписка типу "total + = value", де "total" і "value" мають тип unsigned char:

movf  value,w
addwf total,f

На щось подібне до ARM, навіть якщо у вас є реєстр, попередньо завантажений базовою адресою змінних, код буде більше схожий:

ldr    r0,[r7+value]
ldr    r1,[r7+total]
add    r1,r1,r0
str    r1,[r7+total]

У багатьох випадках компілятор міг би уникати навантажень і зберігання при кожній операції, але на щось подібне до PIC, переваги більшого робочого набору іноді можуть перевищувати обмеження необхідності постійно проходити W.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.