Що означає «реп; nop; " означає в збірці x86? Це те саме, що інструкція "пауза"?


86
  • Що це rep; nopозначає?
  • Це те саме, що pauseінструкція?
  • Це те саме, що rep nop(без крапки з комою)?
  • Яка різниця від простої nopінструкції?
  • Чи поводиться він по-різному на процесорах AMD та Intel?
  • (бонус) Де знаходиться офіційна документація до цих інструкцій?

Мотивація цього питання

Після обговорення в коментарях до іншого питання я зрозумів, що не знаю, що rep; nop;означає збірка x86 (або x86-64). А також я не міг знайти хорошого пояснення в Інтернеті.

Я знаю, що repце префікс, що означає "повторити наступні інструкції cx" (або, принаймні, так було в старій 16-бітовій збірці x86). Відповідно до цієї зведеної таблиці в Вікіпедії , здається , repможуть бути використані тільки з movs, stos, cmps, lods, scas(але , можливо , це обмеження було знято на нових процесорах). Таким чином, я міг би думати rep nop(без крапки з комою) повторити nopоперацію cxразів.

Однак після подальших пошуків я ще більше розгубився. Здається, rep; nopі pause map, і той самий код операції , і pauseмає трохи іншу поведінку, ніж просто nop. Деякі старі листи від 2005 року говорили різні речі:

  • "намагайся не спалювати занадто багато енергії"
  • "це еквівалентно" nop "лише з 2-байтовим кодуванням."
  • "це магія для Intel. Це як" nop, але нехай інший брат HT працює "
  • "це пауза на Intel і швидке заповнення на Athlon"

З такими різними думками я не міг зрозуміти правильного значення.

Він використовується в ядрі Linux (і на i386, і на x86_64 ), разом із цим коментарем: /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */Він також використовується в BeRTOS , з тим самим коментарем.


Відповіді:


75

rep; nopдійсно те саме, що pauseінструкція (код операції F390). Він може бути використаний для монтажників, які ще не підтримують pauseінструкцію. На попередніх процесорах це просто нічого не робило, як nopлише два байти. На нових процесорах, які підтримують гіперпотоки, він використовується як підказка процесору про те, що ви виконуєте спін-петлю для підвищення продуктивності. З довідкової інструкції Intel :

Покращує продуктивність циклів обертання-очікування. При виконанні “циклу обертального очікування” процесор Pentium 4 або Intel Xeon зазнає суворого показнику продуктивності при виході з циклу, оскільки виявляє можливе порушення порядку пам'яті. Інструкція ПАУЗА надає процесору підказку про те, що послідовність кодів є циклом очікування обертання. Процесор використовує цю підказку, щоб у більшості ситуацій уникнути порушення порядку пам'яті, що значно покращує продуктивність процесора. З цієї причини рекомендується розміщувати інструкцію PAUSE у всіх циклах spin-wait.


4
Чи такий же цикл обертання-очікування, що і цикл зайнятого очікування ? Чи стосується це «вдосконалення» лише процесорів з гіперпотоками? (і чому?)
Denilson Sá Maia

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

1
@Brendan, дякую! Я взагалі не розумів, поки ви паралельно не сказали про ітерації циклу.
Проф. Фалькен,

11
@Brendan, О, тепер я розумію! Ці сучасні процесори є суперскалярними , і, отже, вони намагатимуться запускати кілька інструкцій одночасно. Якщо це цикл зайнятого очікування, запуск більшої кількості інструкцій не прискорить, оскільки він просто чекає іншої умови.
Denilson Sá Maia

1
@Denilson: Так, зручність використання гіперпотоків (або просто економія енергії без HT) є однією великою перевагою, але інша - уникнення помилкових спекуляцій при упорядкуванні пам'яті під час виходу із циклу обертання. Без цього pauseваш цикл обертання фактично на один конвеєр очищується повільніше, щоб помітити зміну стану розташування пам'яті, записаного іншим ядром.
Пітер Кордес,

14

rep nop= F3 90 = кодування pause, а також спосіб декодування на старих процесорах, які не підтримують pause.


Префікси (крім lock), які не застосовуються до інструкції, ігноруються на практиці існуючими процесорами.

У документації сказано, що використання repз інструкціями, до яких це не стосується, "зарезервовано і може спричинити непередбачувану поведінку", оскільки майбутні ЦП можуть розпізнати це як частину нової інструкції. Після того, як вони встановлюють будь-яке конкретне нове кодування інструкцій з використанням f3 xx, вони документують, як воно працює на старих процесорах. (Так, простір коду x86 настільки обмежений, що вони роблять такі божевільні речі, і так, це ускладнює декодери.)

У цьому випадку це означає, що ви можете використовувати pauseспін-петлі, не порушуючи компарт назад . Старі процесори, які не знають про pauseце, розшифровуватимуть його як NOP без шкоди, як гарантується введеннямpause вручну ISA посилання Intel для . На нових центральних процесорах ви отримуєте переваги енергозбереження / зручності HT і уникаєте впорядкування пам’яті помилкових спекуляцій, коли пам’ять, на якій ви обертаєтесь, змінюється, і ви залишаєте цикл віджиму.


Посилання на посібники Intel та масу інших корисних речей на інформаційній сторінці wiki тегу x86

Інший випадок, коли безглуздий repпрефікс стає новою інструкцією щодо нових процесорів: lzcntце F3 0F BD /r. На процесорах, які не підтримують цю інструкцію (відсутні прапорці функції LZCNT в їх CPUID), він декодується як rep bsr, який працює так само, як bsr. Отже, на старих центральних процесорах він виробляє 32 - expected_resultі не визначений, коли вхідне значення було нульовим.

Але tzcntі bsfроблять те саме з ненульовими входами, тому компілятори можуть і використовують tzcntнавіть тоді, коли не гарантовано, що цільовий процесор буде запускати його як tzcnt. Процесори AMD працюють швидко tzcnt, повільно bsf, а на Intel вони обидва швидкі. Поки це не має значення для правильності (ви не покладаєтесь на встановлення прапора або на залишення цільової модифікованої поведінки у випадку введення = 0), декодування як tzcntна процесорах, що підтримують це корисно.


Один випадок безглуздого repпрефікса , який, ймовірно , ніколи не розшифровує по- різному: rep ret(тобто не орієнтується конкретний процесором з використовуваним за замовчуванням з допомогою GCC при орієнтації «загальні» процесорів -marchабо -mtune., А не орієнтується AMD K8 або К10) Це буде десятиліттями , перш ніж хто - міг зробити процесор, який декодується rep retяк будь-що інше ret, оскільки він присутній у більшості двійкових файлів у більшості дистрибутивів Linux. Дивіться, що означає `повторний запуск`?


3
repПрефікс також використовується Intel для додавання блокування Перепустки.
Пол А. Клейтон,

Префікси, які не стосуються інструкції, ігноруються. Але згадується, що повторення префіксів ( F2Hі F3H) зарезервовано і може призвести до непередбачуваної поведінки в таблиці 11-3. Вплив префіксів на інструкції SSE, SSE2 та SSE3 . Тому префікс-програма ігнорується для деяких інструкцій, а не для всіх. Тож чи вважається ця функція недокументованою?
Сент-Антаріо,

2
@ St.Antario: Вони формулюють це так, оскільки майбутні центральні процесори можуть визнати це частиною нової інструкції. На всіх реальних процесорах це було так, і як тільки вони встановлюють кодування за допомогою, f3 xxвони документують, як воно працює на старих процесорах.
Пітер Кордес,

1
Префікси (крім блокування), які не застосовуються до інструкції, ігноруються на практиці існуючими процесорами. Задокументовано, що rep movbeпричини #UD, тому repне завжди ігноруються. Навіть якщо це не поширюється на інструкцію в тому сенсі, як це вказано в REP/REPE/REPZ/REPNE/REPNZпосібнику.
Сент-Антаріо

2
@ St.Antario: Цікаво! Загалом, для старих інструкцій непридатні префікси ігноруються. Представляючи нову інструкцію, можна додати більш жорсткі правила, якщо вони вирішать. IDK, чому вони вибрали б саме для цього конкретного випадку.
Пітер Кордес,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.