Чому процесор має 32 регістри?


52

Мені завжди було цікаво, чому процесори зупиняються на 32 регістрах. Це далеко найшвидший шматок машини, чому б просто не зробити більші процесори з більшою кількістю регістрів? Хіба це не означало б менше відвідування оперативної пам’яті?


2
Я думаю, що після певного моменту всі ваші локальні змінні вписуються в регістри. Фактичні дані, з якими ви працюєте, все одно, мабуть, занадто великі
Ніклас Б.

14
Зменшується віддача. Зрозуміло, що регістри "дорожчі" (в різних сенсах), ніж оперативна пам'ять, або ми просто матимемо 8 ГБ регістрів.
Девід Річербі

5
Однією з причин його так швидко є те, що їх багато не буває.
stackErr

5
Існує різниця між кількістю реєстрів, на яких розміщений процесор, і тим, скільки ви можете використовувати одночасно.
Thorbjørn Ravn Andersen

Процесори та графічні процесори приховують затримку в основному кешами та багатопотоковою передачею відповідно. Так, у процесорів є кілька реєстрів, тоді як у графічних процесорах - десятки тисяч. Дивіться мій документ з опитування про файл реєстру GPU, в якому обговорюються всі ці компроміси та фактори.
user984260

Відповіді:


82

По-перше, не всі архітектури процесорів зупинилися на 32 регістрах. Майже всі архітектури RISC, які мають 32 регістри, відкриті в наборі інструкцій, насправді мають 32 цілочисельні регістри та ще 32 регістри з плаваючою точкою (так 64). (Плаваюча точка "додати" використовує різні регістри, ніж ціле число "додати".) В архітектурі SPARC є вікна реєстру. У SPARC ви можете отримати доступ до 32 цілочисельних регістрів одночасно, але регістри діють як стек, і ви можете одночасно натискати та виконувати нові регістри 16. В архітектурі Itanium від HP / Intel було встановлено 128 цілочисельних та 128 регістрів з плаваючою точкою, відкритих у наборі інструкцій. Сучасні графічні процесори від NVidia, AMD, Intel, ARM та Imagination Technologies, всі експонують величезну кількість регістрів у своїх файлах реєстрів. (Я знаю, що це стосується архітектури NVidia та Intel. Я не дуже знайомий з наборами інструкцій AMD, ARM та Imagination, але я думаю, що файли реєстру там також великі.)

По-друге, більшість сучасних мікропроцесорів реалізують перейменування регістрів, щоб усунути непотрібну серіалізацію, викликану необхідністю повторного використання ресурсів, тому базові файли фізичного реєстру можуть бути більшими (96, 128 або 192 регістри на деяких машинах). Це (і динамічне планування) усуває деякі з потреба у компіляторі генерувати стільки унікальних імен реєстру, при цьому надаючи більший файл реєстру для планувальника.

Існує дві причини, через які може бути важко збільшити кількість реєстрів, викритих у наборі інструкцій. По-перше, ви повинні мати можливість вказати ідентифікатори регістрів у кожній інструкції. 32 регістри потребують 5-бітового специфікатора регістрів, тому 3-адресні інструкції (звичайні для архітектури RISC) витрачають 15 з 32 бітів інструкцій саме для того, щоб вказати регістри. Якщо ви збільшили це до 6 або 7 біт, у вас було б менше місця для визначення опкодів і констант. Графічні процесори та Itanium мають значно більші інструкції. Більш великі інструкції коштують: потрібно використовувати більше пам'яті інструкцій, тому поведінка кеш-інструкцій менш ідеальна.

Друга причина - час доступу. Чим більше ви робите пам'ять, тим повільніше отримувати доступ до даних з неї. (Просто з точки зору основної фізики: дані зберігаються у двовимірному просторі, тому якщо ви зберігаєте біт, середня відстань до певного біта становить . Файл реєстру - це просто невелика багатопортова пам'ять, і одне з обмежень для її збільшення полягає в тому, що в кінцевому підсумку вам доведеться починати тактирувати свою машину повільніше, щоб вмістити файл більшого реєстру. Зазвичай з точки зору загальної продуктивності це втрата. O ( nO(n)


1
Я б згадав про 256 FPRs SPARC64 VIIIfx та 32 додаткові безвіконні GPR, досягнуті додаванням інструкції Set XAR, яка надає 13 біт для наступної однієї чи двох інструкцій. Він був орієнтований на HPC, тому кількість реєстрів зрозуміліша. Я також спокусився б пояснити деякі компроміси та методи, пов'язані з більшою кількістю реєстрів; але ти проявив мудрість уникати більш виснажливої ​​(і навіть тоді не вичерпної) відповіді.
Пол А. Клейтон

2
Додавати трохи зменшення переваги більшої кількості регістрів для коду загального призначення може бути доцільним, хоча знайти значущі вимірювання непросто. Я думаю, що Мітч Алсуп згадував у comp.arch, що розширення x86 на 32 регістри, а не 16, отримало б приблизно 3% в порівнянні з (ISTR) 10-15% для обраного розширення регістра 8 на 16. Навіть для ISA-магазину для завантаження, перехід до 64, ймовірно, надає мало користі (принаймні, для поточного GP-коду). (BTW, GPU часто поділяють регістри на потоки: наприклад, одна нитка з 250, що залишає 16 на 16 приватних для інших потоків.)
Пол А. Клейтон

Цікаво побачити, що управління середовищем (отже, альфа-конверсія), часто асоційоване з мовами високого рівня, насправді використовується на рівні реєстру.
бабу

@ PaulA.Clayton Я завжди думав, що IA-64 - це архітектура, яка має найбільшу кількість реєстрів ISA
phuclv

@ LưuVĩnhPhúc SPARC64 VIIIfx був специфічним для HPC. Нещодавно , у Am29k (впроваджений у 1987-8 рр. ) Було 64 глобальних та 128 віконних GPR, що є більше GPR, ніж Itanium (у яких є 8 філійних регістрів та регістр підрахунку циклу, функція яких буде в GPR в деяких інших ISA).
Пол А. Клейтон

16

Ще дві причини обмеження кількості регістрів:

  • Невеликого виграшу слід очікувати: процесор, такий як поточні моделі Intel / AMD x64, має 32 кБайт і більше кеш-пам'яті L1-D, а доступ до кешу L1 зазвичай займає лише один тактовий цикл (порівняно з близько ста тактових циклів для повної єдиної оперативної пам'яті доступ). Тому мало що можна отримати від того, що в регістрах буде більше даних, порівняно з наявністю даних у кеші L1
  • Додаткові обчислювальні витрати. Наявність більшої кількості регістрів створює накладні витрати, які фактично можуть зробити комп'ютер повільніше:
    • У середовищах багатозадачності перемикач завдань, як правило, повинен зберігати вміст усіх регістрів процесу, що залишився в пам'яті, і повинен завантажувати ті, які слід ввести. Чим більше реєстрів у вас, тим довше це займе.
    • Аналогічно, в архітектурах без вікон реєстру каскадні виклики функцій використовують той самий набір регістрів. Отже, функція A, яка викликає функцію B, використовує той самий набір регістрів, що і сама B. Отже, B має зберегти вміст усіх регістрів, які він використовує (які все ще містять значення A), і повинен записати їх перед поверненням (у деяких конвенціях, що викликають, завдання A зберігати вміст свого регістра перед викликом B, але накладні схожі). Чим більше реєстрів у вас, тим довше це заощадження, і тим самим дорожчим стає виклик функції.

Як це працює для кешу L1, щоб у нас не було такої ж проблеми, як для регістрів?
бабу

4
У процесорах високої продуктивності затримка L1 Dcache, як правило, становить 3 або 4 цикли (включаючи генерацію адреси), наприклад, Haswell Intel має 4-х циклічну затримку (не маючи затримки в регістрі залежності від даних, також простіше сховатися в конвеєрі). Dcache також підтримує менше доступу за цикл (наприклад, 2 читання, 1 запис для Haswell), ніж файл реєстру (наприклад, 4 читання, 6 запису для Alpha 21264, який реплікував файл, 2 файли з 4 читаннями швидше, ніж 1 з 8).
Пол А. Клейтон

@ PaulA.Clayton: Якщо кеш L1 має затримку 3-4 циклу, це може припустити, що, можливо, є певна користь, наприклад, мати кілька наборів з 64 слів одноциклічної пам’яті з власним адресним простором у 64 слова та спеціальні вказівки "завантажувати / зберігати прямі", особливо якщо був спосіб висунути всі ненульові значення, за яким слід сказати слово, які слова є ненульовими, а потім спосіб повернути їх назад (нулюючи будь-які регістри, які не вискочили) . Багато методів мають від 16 до 60 слів локальних змінних, тому скорочення часу доступу для тих, хто триває від 3-4 циклів до одного, може здатися корисним.
supercat

@supercat Різні стеки (і глобальні / TLS [наприклад, Knapsack]) кеш-ідеї були представлені в наукових працях, а також такі механізми, як буфер підписів ( PDF ) Фактичне використання, не так вже й багато (здається). Це стає балаканиною (тому, мабуть, має закінчитися або піти в інше місце).
Пол А. Клейтон

4

Багато коду має багато доступу до пам'яті (30% - типова цифра). З цього, як правило, приблизно 2 / 3rds є доступом до читання, а 1/3ds є доступом до запису. Це пов’язано не з тим, що стільки закінчуються регістри, скільки доступ до масивів, доступ до змінних членів об'єкта тощо.

Це має бути зроблено в пам'яті (або кеш даних) завдяки тому, як C / C ++ зроблено (все, що ви можете отримати вказівник, має мати адресу, яку необхідно потенційно зберігати в пам'яті). Якщо компілятор може здогадатися, що ви не будете записувати до змінних вольово-невільно, використовуючи шалені хитрості непрямих покажчиків, він поставить їх у регістри, і це чудово підходить для змінних функцій, але не для глобально доступних (як правило, все, що виходить з малока ()) тому що по суті неможливо здогадатися, як зміниться глобальна держава.

Через це, звичайно, що компілятор зможе зробити що-небудь із більш ніж приблизно 16 загальними регістрами використання. Тому всі популярні архітектори мають приблизно стільки (ARM має 16).

MIPS та інших RISC, як правило, мають 32, оскільки не так складно мати стільки регістрів - вартість досить низька, так що це трохи "чому б і ні?". Більше 32 здебільшого марно і має мінус у тому, щоб зробити файл реєстру довшим доступом (кожне подвоєння кількості регістрів потенційно додає додатковий шар мультиплексорів, що додає трохи більше затримки ...). Це також робить інструкції в середньому трохи довшими - це означає, що при запуску програм, які залежать від пропускної здатності пам'яті інструкцій, ваші додаткові регістри насправді сповільнюють вас!

Якщо ваш процесор є в порядку і не перейменовує реєстр, і ви намагаєтесь робити багато операцій за цикл (більше 3), то теоретично вам потрібно більше реєстрів, оскільки кількість ваших операційних сил за цикл збільшується. Ось чому Itanium має стільки регістрів! Але на практиці, окрім коду, орієнтованого на число з плаваючою комою або SIMD (у якому Itanium був дуже хороший), більшість кодів матиме багато пам’яті, що читає / записує та стрибає, що робить цю мрію більш ніж на 3 ops за цикл неможливою . Це те, що потопило Itanium.

Все зводиться до різниці між обчисленням та виконанням!


2

Хто вам каже, що у процесора завжди є 32 регістри? x86 має 8, ARM 32-розрядний, а x86_64 16, IA-64 128 та багато інших чисел. Ви можете подивитися тут . Навіть MIPS, PPC або будь-які архітектури, які мають 32 регістри загального призначення в наборі інструкцій, кількість набагато більша, ніж 32, оскільки завжди є регістри прапор (якщо такі є), контрольні регістри ..., не включаючи перейменовані регістри та апаратні регістри

Все має свою ціну. Чим більша кількість реєстрів, тим більше роботи ви робите при перемиканні завдань, тим більше місця потрібно в кодуванні інструкцій. Якщо у вас менше зареєстровано, вам не доведеться багато зберігати та відновлювати під час виклику та повернення з функцій чи перемикання завдань із відключенням відсутності регістрів у деякому обчислювальному коді

Причому, чим більший файл реєстру, тим він буде дорожчим і складнішим. SRAM - це найшвидша і найдорожча оперативна пам'ять, тому вона використовується лише в кеш-процесорі. Але це набагато дешевше і займає менше площі, ніж файл реєстру з однаковою ємністю.


2

Наприклад, типовий процесор Intel має "офіційно" 16 цілочисельних і 16 векторних регістрів. Але насправді є ще багато: Процесор використовує "реєструвати перейменування". Якщо у вас є інструкція reg3 = reg1 + reg2, у вас виникли б проблеми, якщо інша інструкція з використанням reg3 ще не закінчилася - ви не змогли виконати нову інструкцію, якщо вона перезаписала reg3 до того, як вона була прочитана попередньою інструкцією.

Тому реальних регістрів існує близько 160 . Отже, проста інструкція, наведена вище, змінюється на "regX = reg1 + reg2, і пам'ятайте, що regX містить reg3". Без реєстру перейменованих видань, поза виконанням порядку було б абсолютно мертвим у воді.


1

Я не інженер-електрик, але думаю, що інша можливість з причини обмеження кількості регістрів - це маршрутизація. Існує обмежена кількість арифметичних одиниць, і вони повинні мати можливість приймати дані з кожного реєстру та виводити їх до кожного реєстру. Це особливо актуально, коли у вас є конвеєрні програми, які можуть виконувати багато інструкцій за цикл.

Проста версія цього матиме складність, роблячи збільшення кількості регістрів незмінним або інакше вимагає перепроектувати маршрутизацію на щось набагато складніше для маршрутизації всього з кращою складністю.O(n2)

Я отримав ідею для цієї відповіді, переглянувши кілька переговорів Івана Годарда на процесорі Mill. Частина нововведення процесора Mill полягає в тому, що ви не можете виводити в довільні регістри - всі виводи висуваються на стек реєстру або "пояс", що, таким чином, зменшує проблеми з маршрутизацією, оскільки ви завжди знаєте, куди піде вихід. Зауважте, у них все ще виникає проблема маршрутизації для отримання вхідних регістрів до арифметичних одиниць.

Див. «Архітектура процесора Mill - пояс» (2 з 9) для постановки проблеми та рішення Мілла.


"Вони повинні мати можливість приймати дані з кожного реєстру та виводити їх до кожного реєстру." - Я б очікував, що це зазвичай реалізується за допомогою шини, не повинно бути окремого з'єднання з АЛУ для кожного реєстру.
користувач253751

1
@immibis: Якщо ви хочете перемістити дані за 300 пікосекунд, шина цього не зробить. І якщо ви хочете перемістити багато даних навколо (наприклад, виконати три вказівки з двома операндами і один результат кожен за один і той же цикл), шина абсолютно не буде працювати.
gnasher729

0

Що стосується MIPS ISA, Hennessy and Patterson, 4-е видання , організація та дизайн комп'ютерів с. 176, відповідає на це конкретне питання безпосередньо:

Менший швидше. Прагнення до швидкості є причиною того, що MIPS має 32 регістри, а не багато інших.

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