Как работает команда x86 pause в spinlock * и может ли она использоваться в других сценариях? - PullRequest
36 голосов
/ 18 января 2011
Команда

pause обычно используется в цикле тестирования spinlock , когда какой-то другой поток владеет спин-блокировкой, чтобы смягчить узкий цикл. Говорят, что это эквивалентно некоторым инструкциям NOP. Может кто-нибудь сказать мне, как именно это работает для оптимизации спин-блокировки? Мне кажется, что даже инструкции NOP являются пустой тратой процессорного времени. Будут ли они уменьшать загрузку процессора?

Другой вопрос: могу ли я использовать инструкцию паузы для других подобных целей. Например, у меня есть занятый поток, который продолжает сканировать некоторые места (например, очередь), чтобы получить новые узлы; однако иногда очередь пуста, и поток просто тратит время процессора. спящий поток и пробуждение его другими потоками может быть вариантом, однако поток является критическим, поэтому я не хочу переводить его в спящий режим. Может ли команда паузы работать для моей цели уменьшить нагрузку на процессор? В настоящее время он использует 100% процессора физического ядра?

Спасибо.

Ответы [ 4 ]

27 голосов
/ 18 января 2011

PAUSE уведомляет процессор о том, что это цикл ожидания спин-блокировки, поэтому доступ к памяти и кэш-памяти может быть оптимизирован. См. Также инструкция паузы в x86 для получения дополнительной информации о том, как избежать ошибочных предположений порядка памяти при выходе из спин-цикла.

PAUSE может на самом деле остановить процессор на некоторое время для экономии энергии. Старые процессоры декодируют его как REP NOP, поэтому вам не нужно проверять, поддерживается ли он. Старые процессоры просто ничего не делают (NOP) как можно быстрее.

Смотри также https://software.intel.com/en-us/articles/benefitting-power-and-performance-sleep-loops


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

Очень долгое вращение все еще очень плохо, даже с PAUSE.

14 голосов
/ 09 октября 2011

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

[источник: руководство Intel]

2 голосов
/ 05 июля 2017

Intel рекомендует использовать инструкции PAUSE только тогда, когда спин-петля очень короткая.

Как я понял из ваших вопросов, ожидания в вашем случае очень длинные. В этом случае спин-петли не рекомендуются.

Вы написали, что у вас есть «поток, который продолжает сканировать некоторые места (например, очередь) для получения новых узлов».

В этом случае Intel рекомендует использовать функции API синхронизации вашей операционной системы. Например, вы можете создать событие, когда новый узел появится в очереди, и просто подождать этого события, используя WaitForSingleObject(Handle, INFINITE). Очередь вызовет это событие всякий раз, когда появится новый узел.

Согласно Руководству по оптимизации Intel, инструкция PAUSE обычно используется с программными потоками, выполняющимися на двух логических процессорах, расположенных в одном и том же ядре процессора, ожидающих снятия блокировки. Такие короткие циклы ожидания имеют тенденцию длиться от десятков до нескольких сотен циклов (то есть 20-500 циклов ЦП), поэтому с точки зрения производительности выгоднее ждать, занимая ЦП, чем уступать ОС.

500 циклов ЦП на процессоре Core i7 7700K с частотой 4500 МГц составляет 0,0000001 секунды, т. Е. 1/10000000-ая секунда: этот цикл 500 циклов ЦП может делать 10 миллионов раз в секунду.

Как видите, эта PAUSE инструкция предназначена для действительно коротких периодов времени.

С другой стороны, каждый вызов функции API, такой как Sleep (), требует больших затрат на переключение контекста, которое может составлять более 10000 циклов; он также несет стоимость переходов от кольца 3 к кольцу 0, что может составлять 1000+ циклов.

Если потоков больше, то доступны ядра процессора (умноженные на функцию гиперпоточности, если таковые имеются), и поток переключится на другой в середине критической секции, ожидая, когда критическая секция из другого потока может действительно нужно looong , по крайней мере, 10000+ циклов, поэтому инструкция PAUSE будет бесполезной.

Пожалуйста, смотрите эту статью для получения дополнительной информации:

Когда ожидается, что цикл ожидания будет длиться тысячи и более циклов, это предпочтительнее уступить операционной системе, вызвав одну из функций API синхронизации ОС, например WaitForSingleObject в ОС Windows.

В заключение: в вашем сценарии инструкция PAUSE не будет лучшим выбором, так как ваше время ожидания велико, в то время как PAUSE предназначен для очень коротких циклов. PAUSE составляет всего 131 такт SkyWell или более поздних процессоров. Например, на Intel Core i7-7700K CPU @ 4,20 ГГц Kaby Lake это всего лишь 31,19 нс.

На более ранних процессорах, таких как Haswell, у меня около 9 циклов. На Intel Core i5-4430 @ 3GHz это 2,81 нс. Таким образом, для длинных циклов лучше отказаться от управления другими потоками, используя функции API синхронизации ОС, чем занимать ЦП с циклом PAUSE.

1 голос
/ 15 октября 2014

Инструкция PAUSE также, по-видимому, используется в процессорах с гиперпоточностью для уменьшения влияния производительности на другие гиперпотоки, предположительно, за счет того, что им отводится больше процессорного времени.

Следующая статья Intel обрисовывает это в общих чертах, и неудивительно, что рекомендуется избегать циклов ожидания на таких процессорах: https://software.intel.com/en-us/articles/long-duration-spin-wait-loops-on-hyper-threading-technology-enabled-intel-processors

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