Что значит "rep; nop;" значит в сборке х86? Это то же самое, что и инструкция «пауза»? - PullRequest
76 голосов
/ 17 августа 2011
  • Что означает 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' только с 2-байтовой кодировкой."
  • "это волшебство для Intel. Это похоже на" нет, но пусть другой брат HT запустится ""
  • "это пауза для intel и быстрое заполнение на Athlon"

Из-за этих разных мнений я не мог понять правильного значения.

Он используется в ядре Linux (на обоих i386 и x86_64 ) вместе с этим комментарием: /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ Он также используется в BeRTOS с тем же комментарием.

Ответы [ 2 ]

66 голосов
/ 17 августа 2011

rep; nop действительно совпадает с инструкцией pause (код операции F390). Может использоваться для ассемблеров, которые еще не поддерживают инструкцию pause. На предыдущих процессорах это просто ничего не делало, как nop, но в двух байтах. На новых процессорах, которые поддерживают гиперпоточность, он используется для подсказки процессору, что вы выполняете спин-петлю для увеличения производительности. От Справочник по инструкции Intel :

Улучшает производительность циклов ожидания при вращении. При выполнении «цикла ожидания вращения» процессор Pentium 4 или Intel Xeon подвергается серьезному снижению производительности при выходе из цикла, поскольку обнаруживает возможное нарушение порядка памяти. Инструкция PAUSE подсказывает процессору, что кодовая последовательность представляет собой цикл ожидания вращения. Процессор использует эту подсказку, чтобы избежать нарушения порядка памяти в большинстве ситуаций, что значительно повышает производительность процессора. По этой причине рекомендуется поместить инструкцию PAUSE во все циклы ожидания вращения.

9 голосов
/ 10 ноября 2015

Префиксы, которые не применяются к инструкции, игнорируются.Однако будущие процессоры могут использовать эту последовательность байтов для кодирования новой инструкции.(да, пространство кода операции x86 настолько ограничено, что они делают сумасшедшие вещи, подобные этому, и да, это усложняет декодеры.)

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


Ссылки на руководства Intel и множество других полезных вещей на вики-странице тега x86: https://stackoverflow.com/tags/x86/info

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


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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...