Что означает «rep; нет; " имеется ввиду в сборке 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 отображается на один и тот же код операции и pauseимеет немного другое поведение, чем просто nop. В одной старой почте от 2005 года говорилось о другом:

  • "постарайтесь не сжигать слишком много энергии"
  • "это эквивалентно 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 подсказывает процессору, что кодовая последовательность представляет собой цикл ожидания с вращением. Процессор использует эту подсказку, чтобы избежать нарушения порядка памяти в большинстве ситуаций, что значительно улучшает производительность процессора. По этой причине рекомендуется помещать инструкцию PAUSE во все циклы ожидания вращения.

ughoavgfhw
источник
4
Является ли цикл с ожиданием такой же , как петля занята-ожидание ? Относится ли это «улучшение» только к гиперпоточным процессорам? (и почему?)
Denilson Sá Maia
11
Да, цикл "спин-ожидание" аналогичен циклу "занято-ожидание". Преимущество также распространяется на процессоры, которые не поддерживают гиперпоточность. Это можно рассматривать как ограничение количества (ненужных) инструкций в конвейере (вместо того, чтобы пытаться выполнять множество итераций цикла параллельно)
Брендан
1
@Brendan, спасибо! Я вообще не понимал, пока вы не сказали про параллельные итерации цикла.
Проф. Фалькен
11
@Brendan, теперь я понял! Эти современные процессоры суперскалярны , поэтому они будут пытаться выполнять несколько инструкций одновременно. Если это цикл «занято-ожидание», выполнение большего количества инструкций не ускорит его, поскольку он просто ждет другого условия.
Денилсон Са Майя
1
@Denilson: Да, совместимость с гиперпоточностью (или просто энергосбережение без HT) - одно большое преимущество, но другое - позволяет избежать неправильных предположений о порядке памяти при выходе из цикла вращения. Без него pauseваш спин-цикл будет фактически на один конвейер медленнее, чтобы заметить изменение состояния области памяти, записанной другим ядром.
Питер Кордес
14

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


Префиксы (кроме lock), которые не применяются к инструкции, на практике игнорируются существующими процессорами.

В документации говорится, что использование repс инструкциями, к которым оно не применяется, «зарезервировано и может вызвать непредсказуемое поведение», потому что будущие процессоры могут распознавать его как часть какой-то новой инструкции. Как только они устанавливают какую-либо конкретную новую кодировку инструкций f3 xx, они документируют, как она работает на старых процессорах. (Да, пространство кода операции x86 настолько ограничено, что они делают такие сумасшедшие вещи, и да, это усложняет декодеры.)

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


Ссылки на руководства Intel и множество других полезных материалов на информационной странице wiki-тега x86

Еще один случай, когда бессмысленный repпрефикс становится новой инструкцией на новых процессорах: lzcntis F3 0F BD /r. На процессорах, которые не поддерживают эту инструкцию (отсутствует флаг функции LZCNT в их CPUID), он декодируется как rep bsr, который выполняется так же, как bsr. Таким образом, на старых процессорах он производит 32 - expected_resultи не определен, когда вход был нулевым.

Но tzcntи bsfсделайте то же самое с ненулевыми входными данными, чтобы компиляторы могли использовать и используют, tzcntдаже если не гарантируется, что целевой ЦП будет запускать его как tzcnt. У процессоров AMD есть быстрые tzcntи медленные bsf, а у Intel они оба быстрые. До тех пор, пока это не имеет значения для правильности (вы не полагаетесь на установку флага или не оставляете неизменное поведение пункта назначения в случае input = 0), tzcntполезно его декодирование, как на процессорах, которые его поддерживают.


Один случай бессмысленного repпрефикса, который, вероятно, никогда не будет декодироваться по-другому: rep retиспользуется по умолчанию gcc при нацеливании на «общие» процессоры (т.е. не нацеленный на конкретный процессор с помощью -marchили -mtune, и не нацеленный на AMD K8 или K10). мог бы сделать процессор, который декодирует rep retчто угодно, кроме ret, потому что он присутствует в большинстве двоичных файлов в большинстве дистрибутивов Linux. См. Что означает `rep ret`?

Питер Кордес
источник
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
@ Сент-Антарио: Интересно! В целом, для старых инструкций неприменимые префиксы игнорируются. При введении новой инструкции можно по желанию добавить более строгие правила. IDK, почему они выбрали это для этого конкретного случая.
Питер Кордес