Чому Intel приховує внутрішнє ядро ​​RISC у своїх процесорах?


89

Починаючи з Pentium Pro (мікроархітектура P6), Intel переробила свої мікропроцесори та використовувала внутрішнє ядро ​​RISC згідно зі старими інструкціями CISC. Оскільки Pentium Pro всі інструкції CISC поділяються на менші частини (uops), а потім виконуються ядром RISC.

На початку мені було зрозуміло, що Intel вирішила приховати нову внутрішню архітектуру та змусити програмістів використовувати "оболонку CISC". Завдяки цьому рішенню Intel могла повністю переробити архітектуру мікропроцесорів, не порушуючи сумісності, це розумно.

Однак я не розумію одного, чому Intel все ще зберігає внутрішні інструкції RISC, приховані на стільки років? Чому б їм не дозволити програмістам використовувати інструкції RISC, як використання старих наборів інструкцій x86 CISC?

Якщо Intel зберігає зворотну сумісність так довго (у нас все ще є віртуальний режим 8086 поруч із 64-бітовим режимом), чому вони не дозволяють нам компілювати програми, щоб вони обходили інструкції CISC і безпосередньо використовували ядро ​​RISC? Це відкриє природний шлях до повільної відмови від набору інструкцій x86, який на сьогодні є застарілим (це головна причина, чому Intel вирішила використовувати ядро ​​RISC всередині, так?).

Дивлячись на нову серію процесорів Intel Core i, я бачу, що вони лише розширюють набір інструкцій CISC, додаючи AVX, SSE4 та інші.


1
зауважте, що є певні процесори x86, де виставляється внутрішній набір інструкцій RISC
phuclv

Відповіді:


90

Ні, набір інструкцій x86, безумовно, не є застарілим. Він популярний як ніколи. Причина, по якій Intel використовує набір RISC-подібних мікроінструкцій всередині, полягає в тому, що їх можна обробити більш ефективно.

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

Що стосується впливу цього формату на "зовнішні" програми, є два моменти:

  • це не стабільний формат. Intel може змінювати його між моделями процесорів, щоб найкраще відповідати конкретній архітектурі. Це дозволяє їм максимізувати ефективність, і ця перевага була б втрачена, якби їм довелося зупинитися на фіксованому, стабільному форматі інструкцій як для внутрішнього, так і для зовнішнього використання.
  • просто нічого не можна отримати, роблячи це. Завдяки величезним, складним процесорам сьогодні декодер є відносно невеликою частиною центрального процесора. Декодування інструкцій x86 робить це складнішим, але на решту процесора це не впливає, тому в цілому виграти дуже мало, особливо тому, що інтерфейс x86 все одно повинен бути там, щоб виконати "застарілий" код . Таким чином, ви навіть не збережете транзистори, які зараз використовуються на інтерфейсі x86.

Це не зовсім ідеальне розташування, але вартість досить мала, і це набагато кращий вибір, ніж проектування ЦП для підтримки двох абсолютно різних наборів інструкцій. (У такому випадку вони, мабуть, в кінцевому підсумку винайдуть третій набір мікрооперацій для внутрішнього використання, просто тому, що їх можна вільно налаштувати, щоб найкраще відповідати внутрішній архітектурі центрального процесора)


1
Хороші бали. RISC - це хороша основна архітектура, де ДОБРІ засоби працює швидко і їх можна правильно впровадити, а x86 ISA, що має історію архітектури CISC, - це просто зараз, макет набору інструкцій з величезною історією та казковим багатством двійкового програмного забезпечення, доступного для нього , а також ефективні для зберігання та переробки. Це не оболонка CISC, це стандартний дефакто-стандарт ISA.
Уоррен П

2
@Warren: з останньої частини, я насправді не думаю. Добре розроблений набір команд CISC є більш ефективним з точки зору зберігання, так, але з кількох тестів , які я бачив, «середній» інструкції x86 що - щось на зразок 4,3 байт в ширину, яка більше , ніж це було б звичайно в архітектура RISC. x86 втрачає велику ефективність зберігання, оскільки був настільки випадково розроблений і розширений протягом багатьох років. Але, як ви кажете, його головна сила - це історія та величезна кількість існуючого двійкового коду.
jalf

1
Я не сказав, що це "добре розроблений CISC", просто "величезна історія". ДОБРІ деталі - це деталі конструкції мікросхем RISC.
Уоррен П

2
@jalf - Якщо перевірити фактичні двійкові файли, розмір інструкцій у x86 становить в середньому близько 3 байт. Звичайно, є набагато довші інструкції, але менші, як правило, домінують у реальному використанні.
серкінг

1
Середня довжина інструкції не є хорошим показником щільності коду: найпоширенішим типом інструкції x86 у типовому коді є завантаження та зберігання (просто переміщення даних туди, де їх можна обробити, і назад до пам'яті, процесори RISC та приблизно ½ CISC мають багато реєстрів, тому не потрібно цього робити багато. Також скільки може зробити одна інструкція (інструкції з озброєнням можуть зробити приблизно 3 речі).
ctrl-alt-delor

20

Реальна відповідь проста.

Основним фактором впровадження процесорів RISC було зменшення складності та збільшення швидкості. Недоліком RISC є зменшена щільність інструкцій, це означає, що той самий код, виражений у форматі RISC, як і формат, потребує більше інструкцій, ніж еквівалентний код CISC.

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

В даний час швидкість пам'яті порівняно зі швидкістю процесора показує велику різницю в тактових частотах. Поточні процесори іноді в п'ять і більше разів швидші, ніж основна пам'ять.

Цей стан технології надає перевагу більш щільному коду, який надає CISC.

Ви можете стверджувати, що кеші можуть пришвидшити процесори RISC. Але те саме можна сказати про CISC процесор.

Ви отримуєте більші покращення швидкості, використовуючи CISC та кеші, ніж RISC та кеші, оскільки кеш однакового розміру більше впливає на код високої щільності, який надає CISC.

Інший побічний ефект полягає в тому, що RISC важче реалізує компілятор. Простіше оптимізувати компілятори для процесора CISC. тощо

Intel знає, що вони роблять.

Це настільки вірно, що ARM має режим вищої щільності коду, який називається Thumb.


1
Також внутрішнє ядро ​​RISC зменшує кількість транзисторів на процесорі CISC. Замість жорсткого підключення кожної інструкції CISC, ви можете використовувати мікрокод для їх виконання. Це призводить до повторного використання інструкцій мікрокоду RISC для різних інструкцій CISC, отже, використовуючи менше площі штампа.
Sil

16

Якщо Intel зберігає зворотну сумісність так довго (у нас все ще є віртуальний режим 8086 поруч із 64-бітовим режимом), чому вони не дозволяють нам компілювати програми, щоб вони обходили інструкції CISC і безпосередньо використовували ядро ​​RISC? Це відкриє природний шлях до повільної відмови від набору інструкцій x86, який на сьогодні є застарілим (це головна причина, чому Intel вирішила використовувати ядро ​​RISC всередині, так?).

Потрібно поглянути на діловий кут цього. Intel насправді намагався відійти від x86, але саме гусак несе золоті яйця для компанії. XScale та Itanium ніколи не наблизились до рівня успіху, який має їх основний бізнес x86.

В основному ви просите, щоб Intel порізала зап’ястя в обмін на теплі пухи від розробників. Підрив x86 не відповідає їхнім інтересам. Все, що змушує більшу кількість розробників не вибирати націлювання на x86, підриває x86. Це, у свою чергу, підриває їх.


6
Так, коли Intel спробувала зробити це (Itanium), ринок просто відповів знизанням плечей.
Warren P

Слід зазначити, що тоді, коли Itanium зазнав невдачі, було безліч факторів, і не лише тому, що це була нова архітектура. Наприклад, розвантаження планувальника процесора до компілятора, який насправді ніколи не досяг своєї мети. Якби Itanium був у 10 разів або в 100 разів швидший за процесори x86, він продавався б як гарячі пиріжки. Але це було не швидше.
Katastic Voyage

5

Відповідь проста. Intel не розробляє ЦП для розробників ! Вони розробляють їх для людей, які роблять покупки рішення , що, до речі, робить кожна компанія у світі!

Intel давно взяла на себе зобов'язання, що, звичайно, їх центральні процесори залишатимуться назад сумісними. Люди хочуть знати, що, купуючи новий комп'ютер на базі Intel, це все їхнє поточне програмне забезпечення буде працювати точно так само, як і на старому комп'ютері. (Хоча, сподіваємось, швидше!)

Крім того, Intel точно знає , наскільки важливим є це зобов'язання, адже колись вони намагалися піти іншим шляхом. Скільки саме людей ти робиш знаєте з процесором Itanium?!?

Можливо, вам це не сподобається, але саме одне рішення - залишатися на x86 - це те, що зробило Intel одним із найбільш впізнаваних бізнес-імен у світі!


2
Я не погоджуюся з натяками на те, що процесори Intel не є зручними для розробників. Програмуючи PowerPC та x86 протягом багатьох років, я переконався, що CISC набагато зручніший для програмістів. (Зараз я працюю в Intel, але я вирішив це питання ще до того, як мене прийняли на роботу.)
Джефф,

1
@Jeff Це зовсім не було моїм наміром! Питання полягало в тому, чому Intel не відкрила набір інструкцій RISC, щоб розробники могли ним скористатися. Я нічого не говорив про те, що x86 не підходить для розробників. Я сказав, що такі рішення, як це не було прийнято рішення з розробниками на увазі , але, скоріше, були суворо ділові рішення.
гео

5

Відповідь @ jalf охоплює більшість причин, але є одна цікава деталь, про яку він не згадує: Внутрішнє ядро, подібне до RISC, не призначене для запуску набору інструкцій на зразок ARM / PPC / MIPS. Податок x86 сплачується не лише в енергоємних декодерах, але певною мірою у всьому ядрі. тобто це не просто кодування інструкцій x86; це кожна інструкція з дивною семантикою.

Давайте зробимо вигляд, що Intel створила режим роботи, де потік інструкцій був чимось іншим, ніж x86, з інструкціями, які безпосередньо відображалися в uops. Давайте також зробимо вигляд, що кожна модель процесора має свою ISA для цього режиму, тому вони все ще можуть змінювати внутрішні елементи, коли їм заманеться, і виставляти їм мінімальну кількість транзисторів для декодування інструкцій цього альтернативного формату.

Імовірно, у вас все одно залишиться однакова кількість регістрів, зіставлених із архітектурним станом x86, тому операційні системи x86 можуть зберігати / відновлювати його на контекстних комутаторах, не використовуючи набір команд для конкретного процесора. Але якщо ми викинемо це практичне обмеження, так, ми могли б отримати ще кілька регістрів, оскільки ми можемо використовувати приховані тимчасові регістри, які зазвичай зарезервовані для мікрокоду 1 .


Якщо ми просто маємо альтернативні декодери без змін на наступних етапах конвеєра (блоки виконання), цей ISA все одно матиме багато ексцентриситетів x86. Це була б не дуже приємна архітектура RISC. Жодна окрема інструкція не була б дуже складною, але деякі інші божевілля x86 все одно були б там.

Наприклад: зсуви вліво / вправо залишають прапорець "Переповнення" невизначеним, якщо кількість зсувів не дорівнює одиниці, і в цьому випадку OF = звичайне виявлення переповнення з підписом. Подібне божевілля для обертається. Однак виставлені інструкції RISC можуть забезпечувати зрушення без прапорів тощо (дозволяючи використовувати лише один або два з декількох uops, які зазвичай входять до деяких складних інструкцій x86). Тож це насправді не є головним контраргументом.

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


Кодування інструкцій, ймовірно, не було б фіксованого розміру, оскільки одиничні оцифровування можуть містити багато даних. Набагато більше даних, ніж має сенсу, якщо всі Insns однакового розміру. Один мікрозлитий uop може додавати 32-бітний негайний і операнд пам'яті, який використовує режим адресації з 2 регістрами та 32-бітним переміщенням. (У SnB та пізніших версіях лише режими адресації з одним регістром можуть запобігати операціям ALU).

uops дуже великі і не дуже схожі на інструкції ARM із фіксованою шириною. 32-бітний набір інструкцій з фіксованою шириною може одночасно завантажувати лише 16-бітові безпосередні дані, тому для завантаження 32-бітної адреси потрібна пара негайного завантаження низької половини / навантаження високої-безпосередньої пари. x86 не повинен цього робити, що допомагає не бути жахливим, оскільки лише 15 регістрів GP обмежують можливість зберігати константи в регістрах. (15 - це велика допомога для 7 реєстрів, але подвоєння знову до 31 допомагає набагато менше, я думаю, було знайдено деяке моделювання. RSP, як правило, не є загальним призначенням, тому це більше як 15 регістрів GP та стек.)


TL; Анотація DR:

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


Внутрішні загальні формати в інтерфейсному та задньому інтерфейсах

Дивіться також режими Micro fusion та адресації для одного випадку відмінностей у тому, що формати інтерфейсу та інтерфейсу uop можуть представляти на процесорах Intel.

Примітка 1 : Є кілька "прихованих" реєстрів, що використовуються як тимчасові мікрокоди. Ці регістри перейменовані так само, як архітектурні регістри x86, тому команди multi-uop можуть виконувати не в порядку.

наприклад, xchg eax, ecxна процесорах Intel декодується як 3 uops ( чому? ), і найкраще припустимо, що це MOV-подібні uops, які це роблять tmp = eax; ecx=eax ; eax=tmp;. У такому порядку, оскільки я вимірюю латентність напрямку dst-> src при ~ 1 циклі, проти 2 для іншого шляху. І ці переміщення uops не схожі на звичайні movінструкції; вони, схоже, не є кандидатами на ліквідацію мов із нульовою затримкою.

Дивіться також http://blog.stuffedcow.net/2013/05/measuring-rob-capacity/, де згадується про спробу експериментального вимірювання розміру PRF та необхідність врахування фізичних реєстрів, що використовуються для збереження архітектурного стану, включаючи приховані регістри.

У інтерфейсі після декодерів, але перед етапом видачі / перейменування, який перейменовує регістри у файл фізичного реєстру, внутрішній формат uop використовує номери регістрів, подібні до номерів регістра x86, але має місце для адреси цих прихованих регістрів.

Формат uop дещо відрізняється всередині невпорядкованого ядра (ROB і RS), він же back-end (після етапу видачі / перейменування). Файли фізичного реєстру int / FP мають по 168 записів у Haswell , тому кожне поле реєстру в uop має бути достатньо широким для адресування такої кількості.

Оскільки перейменовувач знаходиться там, у HW, нам, мабуть, було б краще використовувати його, замість того, щоб подавати статично заплановані інструкції безпосередньо на задній план. Отже, ми б почали працювати з набором регістрів, великих як архітектурні регістри x86 + тимчасові мікрокоди, не більше того.

Бек-енд розроблений для роботи з інтерфейсним перейменовувачем, який дозволяє уникнути небезпеки WAW / WAR, тому ми не могли використовувати його як впорядкований процесор, навіть якби ми цього хотіли. Він не має блокування для виявлення цих залежностей; це обробляється шляхом видачі / перейменування.

Це може бути акуратно, якби ми могли завантажувати uops в задній кінець без вузького місця на етапі видачі / перейменування (найвужча точка в сучасних конвеєрах Intel, наприклад, 4-шир. На Skylake проти 4 ALU + 2 завантаження + 1 порт для зберігання в задній кінець). Але якщо ви це зробили, я не думаю, що ви можете статично планувати код, щоб уникнути повторного використання реєстру та наступу на результат, який все ще потрібен, якщо помилка кешу затримала навантаження на довгий час.

Отже, нам в значній мірі потрібно подавати uops до етапу видачі / перейменування, можливо, лише минаючи декодування, а не загальний кеш чи IDQ. Тоді ми отримуємо нормальний OoO exec з розумним виявленням небезпеки. Таблиця розподілу регістрів призначена лише для перейменування 16 + декількох цілочисельних регістрів у ціле число PRF із 168 записів. Ми не могли очікувати, що HW перейменує більший набір логічних регістрів на однакову кількість фізичних регістрів; для цього потрібен більший RAT.


-3

Чому вони не дозволяють нам компілювати програми, щоб вони обходили інструкції CISC і безпосередньо використовували ядро ​​RISC?

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


1
Я не думаю, що це має сенс. RISC може використовувати мікрокод, особливо якщо ми говоримо про просто додавання декодерів RISC до інтерфейсу x86.
Пітер Кордес,

2
Це все ще неправильно. Нові інструкції AES (і майбутні інструкції SHA) та інші речі, такі як PCLMULQDQ, мають спеціальне обладнання. На Haswell AESENC розшифровується до єдиного uop ( agner.org/optimize ), тому він точно не мікрокодований взагалі. (Декодерам потрібно лише активувати мікрокод-послідовник ПЗУ для отримання інструкцій, які декодують більше ніж 4 UPS .)
Пітер Кордес,

1
Ви маєте рацію, що деякі нові інструкції просто використовують наявну функціональність, недоступну для інструкцій x86. Хороший приклад може бути BMI2 SHLX , який дозволяє робити змінний підрахунок зміна без введення лічильника в CL, і без якого додаткових микроопераций потрібно для обробки семантики прапора дерьмово x86 (прапори не модифікується , якщо величина зсуву дорівнює нуль, так що SHL r/m32, clмає вхідна залежність від FLAGS і декодується до 3 опер на Skylake. Однак це було лише 1 uop на Core2 / Nehalem, проте, згідно з тестуванням Agner Fog.)
Пітер Кордес,

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