Як працює прогнозування галузей, якщо вам все-таки доведеться перевіряти умови?


30

Я читав популярну відповідь про передбачення філії з https://stackoverflow.com/q/11227809/555690 , і щось мене бентежить:

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

Якщо ви гадаєте щоразу правильно, поїзд ніколи не повинен буде зупинятися.

Якщо ви занадто часто здогадуєтесь, поїзд витратить багато часу на зупинку, резервне копіювання та повторний пуск.

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

Що я намагаюся сказати, чи не прогнозування галузей точно таке, як взагалі не передбачення гілок, тому що ви все одно робите ті самі умовні перевірки? (очевидно, я помиляюся, але не розумію)


1
Ця стаття у Вікі робить досить непогану роботу, пояснюючи це.
Ендерленд

8
Сучасний процесор є конвеєрним і може робити кілька речей одночасно. Таким чином, він може почати виконувати свої здогадки, поки все ще з'ясувати, чи правильно він здогадався. Якщо здогад був правильним, трубопровід продовжує працювати. При неправильній здогадці трубопровід викидається, а виконання перезапускається з точки "правильної відповіді".
маркерний простір

2
Пов'язане читання: трубопровід . Я також рекомендую перечитати прийняту відповідь на це питання ТА, як це відповідає на ваше запитання тут.

Відповіді:


19

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

Зазвичай за умовою негайно слідує умовна інструкція гілки, яка або розгалужується, якщо умова оцінюється як ІСТИНА, або пропадає, якщо умова оцінюється на ЛІЖНУ. Це означає, що є два різних потоки інструкцій, які можуть бути завантажені в конвеєр після інструкції про стан та інструкції гілки, залежно від того, чи умова оцінюється як ІСТИНА, або ЛЖА. На жаль, одразу після завантаження інструкції про стан та інструкції з гілки, процесор ще не знає, до чого оцінюватиметься умова, але він все ще повинен продовжувати завантажувати матеріали в конвеєр. Таким чином, він вибирає один із двох наборів інструкцій, що ґрунтуються на здогаді щодо того, до чого оцінюватиметься умова.

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

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

Поправка

У відповідь на коментар StarWeaver, щоб дати уявлення про те, що повинен зробити процесор, щоб виконати одну інструкцію:

Розглянемо щось таке просте, як те, MOV AX,[SI+10]що ми люди наївно вважаємо "завантаження AX словом у SI плюс 10". Приблизно, процесор повинен:

  1. випромінювати вміст ПК ("реєстр лічильників програм") на шину адреси;
  2. читати опкод інструкції з шини даних;
  3. приріст ПК;
  4. розшифруйте опкод, щоб зрозуміти, що з ним робити;
  5. випромінювати вміст ПК на адресну шину;
  6. читати операнд інструкцій (у цьому випадку 10) з шини даних;
  7. приріст ПК;
  8. подати операнда та СІ в суматор;
  9. випромінюють результат суматора на адресну шину;
  10. зчитування AX з шини даних.

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

Тепер, врахуйте, що існують більш складні режими адресації, як MOV AX, [DX+SI*4+10], і навіть набагато складніші інструкції, як-от, MUL AX, operandякі насправді виконують петлі всередині процесора для обчислення їх результату.

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


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

1
@StarWeaver мені сподобався ваш коментар, тому я змінив свою відповідь, щоб вирішити його.
Майк Накіс

1
Нічого собі, приємного пояснення. Я, як правило, забуваю, скільки переходить у просто переміщення слів у більш корисні місця. Я все ще візуалізую процесор як набір пічних пічних піч, хоча: 3.
StarWeaver

Варто мати на увазі, що питання про переповнення стека, пов’язане з ОП - те, що має 1,3 мільйона переглядів, яке, ймовірно, ввело понад 1 мільйон програмістів до раніше незнайомого факту, що «передбачення гілок» навіть існує - є прикладом у Java . Для таких людей, як я, які звикли працювати на рівні абстракції, яку нам надають такі мови, як Java, навіть MOV AX,[SI+10]чужа, а не "проста"; Більшість програмістів сьогодні ніколи не писали зборів. Ми не «наївно думаємо» про це як про щось, що означає.
Марк Амерді

@MarkAmery добре, гаразд, я вважав, що це досить очевидно, що під "ми люди" я маю на увазі "ми, люди, які наважуємося написати збірку". Справа в тому, що навіть програмісти з мовної збірки не думають про конвеєр весь час, а то і зовсім.
Майк Накіс

28

Подумайте про це як про подорож без GPS. Ви приходите на перехрестя і думаєте, що вам потрібно повернути, але не зовсім впевнені. Тож ви повороту, але попросіть свого пасажира перевірити карту. Можливо, ви три милі вниз по дорозі до того часу, як закінчите сперечатися про те, де ви знаходитесь. Якби ви мали рацію, ви на три милі далі, ніж ви були, якби ви зупинилися і сперечалися перед поворотом. Якщо ви помилялися, вам доведеться розвернутися.

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


2
Це пояснення акуратне.
гострий зуб

2

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

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

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


1

Коротка форма:

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

Приклад псевдокоду:

int globalVariable;
int Read(int* readThis, int* readThat)
{
    if ((globalVariable*globalVariable % 17) < 5)
       return *readThis;
    else
       return *readThat;
}

Вищевказаний код перевіряє стан і на основі результату йому потрібно повернути або значення, збережене в пам'яті, addThisабо значення, збережене в readThat. Якщо передбачення гілки прогнозує, що умова буде true, CPU вже буде читати значення, збережене в пам'яті addThis, виконуючи обчислення, необхідне для оцінки ifоператора. Це спрощений приклад.


1

Так, стан перевіряється в будь-якому випадку. Але перевага галузевого прогнозування полягає в тому, що ви можете виконувати роботу, а не чекати результату перевірки стану.

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

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

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

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

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