Перейменування регістрів
В архітектурі комп'ютера, перейменування регістрів (англ. Register Renaming) — це метод ослаблення взаємозалежностей команд, що виконуються процесором, при позачерговому виконанні.
У тому випадку, якщо відповідно з двома або більше командами необхідно здійснити запис даних в один регістр, їх коректне позачергове виконання стає неможливим (пізніша команда не може бути оброблена до завершення більш ранньої) навіть у тому випадку, якщо при цьому немає залежності по даним. Такі взаємозалежності часто називають помилковими (у разі істинної залежності існує залежність і за даними).
Так як кількість архітектурних регістрів зазвичай обмежена (наприклад, стандартно архітектура x86 передбачає тільки вісім регістрів загального призначення), ймовірність виникнення помилкових взаємозалежностей досить велика, що може призвести до зниження продуктивності процесора.
Перейменування регістрів являє собою перетворення програмних посилань на архітектурні регістри в посилання на фізичні регістри і дозволяє послабити вплив помилкових взаємозалежностей за рахунок використання великої кількості фізичних регістрів замість обмеженої кількості архітектурних (так, наприклад, x86-сумісні процесори архітектури Intel P6 містять 40 фізичних регістрів). При цьому процесор відстежує, стан яких фізичних регістрів відповідають стану архітектурних, а видача результатів здійснюється в порядку, який передбачений програмою.
Означення проблеми
У регістровій машині програми складаються з команд, які працюють на певних значеннях. Команди повинні давати імена цим значенням для того, щоб їх можна було відрізнити одне від одного. Звичайна команда повинна вказати, додати X, додати Y і результат записати в Z. В командах є X, Y і Z і імена місць зберігання.
Щоб мати компактний код команд, більшість наборів команд процесора мають невеликий набір в спеціальних місцях, які можуть бути безпосередньо названі. Наприклад, набір команд для x86 архітектури має 8 цілих регістрів, x86-64 має 16, багато RISC мають 32, а IA-64 - 128. У невеликих процесорах ім'я цієї області пам'яті відповідає елементам регістрового файлу.
Різні команди можуть займати різну кількість часу; наприклад процесор здатний виконувати сотні команд, поки відбувається одне завантаження із оперативної пам'яті. Більш короткі команди виконуються, поки це завантаження завершиться, так команди закінчують роботу у порядку відмінному від порядку з оригінальної програми. Позачергове виконання використовується в останніх високопродуктивних процесорах для досягнення деякого збільшення швидкості.
Розглянемо, як цей шматок коду працює процесорі, що може змінити порядок команд:
# | Команди |
---|---|
1 | R1 = M[1024] |
2 | R1 = R1 + 2 |
3 | M[1032] = R1 |
4 | R1 = M[2048] |
5 | R1 = R1 + 4 |
6 | M[2056] = R1 |
Команди 4, 5 і 6 є незалежними командами 1, 2 і 3, але процесор не може завершити 4 доти, поки 3 не буде зроблено, в іншому випадку в 3 команди буде записано некоректне значення. Ці обмеження можуть бути усунені шляхом зміни імен деяких регістрів:
# | Команда | # | Команда | |
---|---|---|---|---|
1 | R1 = M[1024] |
4 | R2 = M[2048] | |
2 | R1 = R1 + 2 |
5 | R2 = R2 + 4 | |
3 | M[1032] = R1 |
6 | M[2056] = R2 |
Зараз команди 4,5 і 6 можуть виконуватися паралельно з 1, 2 і 3, так що програма може виконувати свою роботу швидше.
Компілятор виявив різні команди і спробував призначити їх на інший регістр, коли це було можливо. Тим не менш, існує скінченна кількість імен регістру які можуть бути використані в асемблерному коді. Багато високопродуктивних процесорів мають більше фізичних регістрів, ніж підтримується архітектурою системи команд, так що вони перейменовують регістри в апаратному забезпеченні, щоб досягти додаткового паралелізму.
Конфлікти даних
Коли більш ніж одна команда використовує певне місце як операнд, або читаючи звідти, або записуючи туди, виконання цих команд у порядку відмінному від заданого початковою програмою може призвести до таких трьох конфліктів даних:
- Читання після запису (RAW): При читанні з регістра або комірки пам'яті, повинно повернути значення розміщене там останнім записом в програмному порядку, а не якимсь іншим записом. Це згадується як істинна залежність або залежність потоку даних, і вимагає, щоб інструкції виконувались в заданому програмою порядку.
- Запис після запису (WAW): Послідовні записи в певному регістрі або пам'яті, повинні залишити це місце із результатом другого запису. Це може бути вирішено шляхом знищення (синоніми: скасування, анулювання) першого запису, якщо це необхідно. WAW залежності також відомі як залежності виведення.
- Запис після читання (WAR): При читанні з регістра або пам'яті повинно повертатися останнє значення, записане в цю область пам'яті, а не те, яке там з'явилось там після цього запису. Це свого роду помилкова залежність, яка може бути вирішена шляхом перейменування. WAR залежність також відома як анти-залежність.