Як ЦП може доставити більше однієї інструкції за цикл?


41

Інструкція Вікіпедії на другу сторінку говорить, що i7 3630QM постачає ~ 110 000 MIPS на частоті 3,2 ГГц; це було б (110 / 3,2 інструкції) / 4 ядра = ~ 8,6 інструкцій за цикл на ядро ​​?! Як одне ядро ​​може передавати більше однієї інструкції за цикл?

Наскільки я розумію, трубопровід повинен мати можливість отримувати лише один результат за добу.

Це мої думки:

  • Внутрішня частота насправді вище 3,2 ГГц
  • Деякі частини процесора асинхронні таким чином, що покірна людина, як я, не може зрозуміти
  • На ядро ​​існує декілька паралельних трубопроводів
  • Трубопровід може забезпечити більше, ніж результат за добу, інструкція може пропустити етапи конвеєра, і є декілька попередніх програм, щоб не відставати
  • Я щось пропускаю

1
Він доставляє 110 000 Mhrystone MIPS, тож DMIPS, а не MIPS - це те, що я бачу безпосередньо - можливо, це може змінити ситуацію? Дивіться en.wikipedia.org/wiki/Dhrystone

Відповіді:


44

По- перше, в якості коментаря Кіла в і відповідь Turbo Джея відзначаєте, вимір було 113,093 Dhrystone MIPS НЕ рідної MIPS.

Мікроархітектура Ivy Bridge i7 3630QM може здійснювати лише 4 злиті мкОп за цикл, хоча може розпочати виконання 6 мкОс за цикл. (Кількість зрощених мкОп в сліді коду приблизно дорівнює кількості інструкцій; деякі складні інструкції декодуються в кілька мкОп, які не злиті, а деякі пари інструкцій можуть бути злиті в один µop, наприклад, порівняння негайно з подальшим умовним стрибком.)

Дві ваші міркування щодо того, як можна виконати кілька інструкцій за один цикл, цілком справедливі і використовуються в фактичних процесорах. Ваші перші міркування про те, що використовується швидший внутрішній годинник, використовувались в оригінальних ALU-колах Pentium 4. Ці АЛУ були тактовані з подвійною частотою решти ядра, яка була вже відносно високою.

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

HyperSPARC використовував кілька споріднену техніку, каскадні АЛУ. HyperSPARC передав результати з двох АЛУ в третій АЛУ. Це дозволило виконати дві незалежні та третю залежну операцію в одному циклі.

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

Існує також кілька інших шансів та закінчень виконання інструкцій, які, можливо, варто відзначити. Деякі операції можна ефективніше виконувати поза звичайними підрозділами виконання. Методика усунення переміщення використовує перейменування реєстру в процесорах, що не є в порядку, для виконання операцій переміщення під час перейменування реєстру; переміщення просто копіює фізичний номер реєстру з однієї позиції в таблиці перейменування (називається таблицею псевдоніму реєстру) в іншу. Це не тільки збільшує ширину виконання, але й усуває залежність. Ця методика застосовувалася на початку x87 на базі стека, але зараз широко використовується у високопродуктивних процесорах x86 x86. (Використання руйнівних інструкцій з двома операндами в x86 робить усунення переміщення більш корисним, ніж було б у типовому RISC.)

Метод, схожий на усунення переміщення, - це керування інструкціями щодо обнулення регістру під час перейменування. Надаючи ім’я регістру, що забезпечує нульове значення, інструкція очищення регістру (наприклад, xor або віднімання, коли обидва операнди є одним і тим же регістром) може просто вставити це ім'я в таблицю перейменування (RAT).

Інша методика, яка використовується деякими процесорами x86, знижує витрати на операції push і pop. Зазвичай інструкція, що використовує покажчик стека, повинна буде дочекатися повного циклу попереднього натискання або спливаючого вікна, щоб оновити значення для покажчика стека. Визнаючи, що push і pop лише додають або віднімають невелике значення до покажчика стека, можна паралельно обчислити результати декількох додавань / підрозділів. Основна затримка додавання - це розповсюдження перенесення, але при малих значеннях більш значущі біти базового значення - у цьому випадку покажчик стека - матимуть не більше одного переносу. Це дозволяє оптимізацію, подібну оптимізації переносу-вибору, застосовувати до декількох додань малих значень. Крім того, оскільки покажчик стека зазвичай оновлюється лише константами,

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

З теоретичної сторони були запропоновані інші методи. Невеликі постійні, окрім нуля, можуть підтримуватися в RAT, і з деякими простими операціями, які використовують або надійно виробляють такі невеликі значення, можна обробити рано. ("Фізичний вклад до фізичного реєстру", Мікко Х. Ліпасті та ін., 2004 р.) Запропонував використовувати RAT як засіб зменшення кількості регістрів, але ідея може бути розширена для підтримки завантаження невеликих безпосередніх та простих операцій на невеликі числа.)

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

Передбачення значення може бути використане для збільшення кількості операцій, які можна виконати паралельно шляхом усунення залежностей. Індикатор значення на основі кроку схожий на оптимізацію pop / push оптимізованого двигуна стека, згаданого раніше. Він може обчислювати кілька доповнень, переважно паралельно, знімаючи серіалізацію. Загальна ідея прогнозування вартості полягає в тому, що з передбачуваним значенням залежні операції можуть тривати без зволікань. (Передбачення напряму та цільове передбачення є фактично лише дуже обмеженою формою прогнозування значення, що дозволяє отримувати наступні інструкції, які залежать від "значення" гілки - взятої чи ні - і наступної адреси інструкції, іншого значення.)


приголомшливий! Дякую за цінну інформацію. Чи можете ви запропонувати книгу, де я можу прочитати всі ці архітектурні прийоми?
безробітний

@workless Після того, як ви вийдете за основи конвеєрного та позамовного виконання надскалярного виконання (що охоплюється більшістю підручників з архітектури комп'ютерів), найкращі джерела інформації - це, мабуть, описи конкретних процесорів мікроархітектури (наприклад, стаття про Haswell, пов'язана у відповіді gnasher729 ) та в наукових роботах (ISCA та MICRO [конференції], як правило, є хороші документи; HPCA, PACT, ASPLOS і, можливо, деякі інші також мають гарну репутацію). Енді Глі (мабуть, найвідоміший своєю роботою над Pentium Pro) ...
Пол А. Клейтон

1
... працював над вікі CompArch, яка представляла б більш вдосконалені концепції, але прогрес був повільним, і його, мабуть, зламали деякий час тому, і тепер лише видається повідомлення про помилку ( semipublic.comp-arch.net/wiki ). Він має намір відновити вікі (оригінальний текст зберігся), використовуючи різні програми вікі (у нього були деякі проблеми з програмним забезпеченням, яке він використовує, і сприймає це як можливість вдосконалити), але "пройде час".
Пол А. Клейтон

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

@ PaulA.Clayton - два захоплення цієї сторінки знаходяться на Wayback. 20 грудня 2013 року та 14 лютого 2014 року . Я не знаю, чи передували цим заходам проблеми зі сторінкою. На жаль, коли я спробував відвідати ці сторінки на Wayback, я отримав повідомлення " Промінь. Машина, яка обслуговує цей файл, зникла. Ми працюємо над цим ", тому я не впевнений, що можна побачити на цих сторінках .
Кевін Феган

10

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

Запорукою розуміння ефективності сучасних процесорів є усвідомлення того, що вони є надзвичайними . З Вікіпедії (моє наголос):

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

Ці сучасні процесори мають кілька одиниць виконання на одне ядро, як ви здогадалися. Гіпер-різьблення цікаво врахувати, деякі частини трубопроводу дублюються, а деякі - ні.

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

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

  • Результати попередніх інструкцій недоступні.
  • Кеш пропускає.
  • Розгалуження коду, яке призведе до недійсності вже отриманих інструкцій (читайте про передбачення гілок тут і тут ).

Сучасні компілятори намагаються допомогти з багатьма перерахованими вище пунктами, потім процесор бере на себе. Для гарного прикладу дивіться це питання в іншому місці Stackexchange, де виділяється важлива різниця між двома інструкціями, які можуть робити те саме (за деяких обставин). Однак одне може бути "швидшим", ніж інше на деяких процесорах завдяки використаному виконуваному блоку.

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


дякую за пояснення та дуже цікаві посилання. Як замітка Cell виглядає дуже цікаво, я з нетерпінням чекаю докладніше вивчити архітектури процесора ^ _ ^. "" У x86 використовується "суперпіпелін", як описано вище. Родина Cell використовує "синергетичний" підхід, що включає дев'ять міні-процесорів. Це правда, що кожен міні-процесор дотримується в основному порядку трубопроводу, у міні-процесора є кілька паралельних надскалярних трубопроводів, а не один трубопровід. "" "
безробітний

3

Як ви думаєте, що трапилося: усі інженери Intel, AMD та IBM прочитали, що конвеєр може забезпечити лише один результат за цикл, і вони сказали: «Ну добре, це вже тоді, не можна робити такі процесори швидшими». Або вони прочитали це і сказали: "Не вдається досягти більше одного результату за цикл? Ми побачимо про це!".

Наприклад, для кращого ознайомлення з архітектурою Haswell ви можете перейти за цим посиланням http://www.realworldtech.com/haswell-cpu/ або просто перейти на веб-сайт Intel, і там ви знайдете трохи документації.

Кожне ядро ​​процесора Haswell має величезну кількість одиниць виконання, які можуть виконувати операції незалежно один від одного, тому паралельно можна виконувати кілька операцій. Далі процесор Haswell має кілька одиниць виконання, які обробляють векторні операції розміром до 256 біт. Операція вектора може, наприклад, виконати чотири операції з плаваючою точкою з подвійною точністю або вісім операцій з плаваючою точкою з одною точністю в одній векторній операції. І нарешті, процесор Haswell підтримує "злиті множини-додавання", що означає, що обчислення разів b плюс c - це лише одна операція.

Теоретичний максимум, оскільки Haswell має дві одиниці, здатні злити з множенням додавання, - це дві злиті операції множення додавання за цикл, кожна операція робить вісім одноточних множень плюс додавання або 32 одиничних операції з плаваючою точкою.

Процесор 3630 не входить в останній прейскурант Intel, але є такі моделі, як 3740QM з чотирма ядрами. Тож замість 32 можна отримати 128 операцій з плаваючою комою за тактовий цикл. Це теоретичний максимум. Досягнення половини цього в реальному житті - це складне завдання, але не неможливе для відповідних завдань. Є й інші процесори, доступні до 15 ядер (за ціни, за які не заплатять навіть найзапекліші фанатики ігор).

Отже, у вас є комбінація декількох множників:

  1. Кілька ядер на процесор.
  2. (Hyperthreading, не згаданий раніше, дозволяє наблизитися до теоретичних меж)
  3. Об'єднана операція множення додавання робить дві арифметичні операції, рахуючи лише одну.
  4. 256-бітні вектори, які роблять 8 операцій, рахуючи лише один.
  5. Дві векторні одиниці виконання, здатні обробляти злито-множимо додавання.

8,6 операцій за цикл досягти не надто складно. Навіть 8,6 операцій за цикл на ядро ​​не надто складно.


Цікаво, чи було б практичним чи вигідним розробити процесор з ядрами, на яких працює x86, і з деякими, які виконують набір інструкцій, оптимізований для суперскалярної поведінки. Я знаю, що Intel і AMD роблять деякі надзвичайно дивовижні речі, щоб подолати обмеження в наборі інструкцій x86, але в деяких випадках я думаю, що знання деяких речей, які не може виразити поточний набір інструкцій, було б корисним. Наприклад, окремі версії ADDінструкцій, що базуються на тому, чи слід переповнення залишити без змін, або слід встановити, коли виникне переповнення (і залишити його, якщо його немає).
supercat

1
Мені прикро, що в цей день і вік багато мов за замовчуванням не перевіряють переповнення. Я знаю, що Java в значній мірі застрягла від семантичних вимог, але в таких мовах, як C #, які включають як атрибути арифметичних операцій, і для захоплення, і не захоплення, єдиною вагомою причиною я бачу не захоплювати переповнення, тому що потрібно вести обертальну поведінку. В даний час перевірка переповнення може накласти значне покарання за швидкість, але якщо машинна мова була розроблена навколо ідеї, що захоплення переповнення не повинно бути точним, доки код може гарантувати, що до роботи не відбулося переповнення ...
supercat

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

... здавалося б, це повинно допомогти зменшити залежність виконання.
supercat

2

Орієнтовний показник Drystone складається з 1984 року, а відповідна номінальна машина MIX VAX не є дуже ефективною в сучасних умовах. Навіть Cortex M3 забезпечує 1,25 DMPIS / МГц.

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


1

Я дуже багато навчився від Джона "Ганнібала" Сторса Ars Technica від чудових і обширних статей на тему мікропроцесорної архітектури. Статті трохи датовані (вони здаються приблизно з 2004 року), але все ще дуже актуальні.

Деякі посилання на наступну частину статті порушені, однак, здається, ви можете їх виправити, ретельно порівнявши URL-адресу першої частини та m-порушену URL-адресу наступної сторінки (наприклад, додавши десь в URL-адресу).

(так, це прославлена ​​відповідь лише для посилань, вибачте; статті занадто гарні, щоб не згадувати про них)

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