Ответ 1
Представьте себе, как процессор выполнит типичный цикл ожидания ожидания:
1 Spin_Lock:
2 CMP lockvar, 0 ; Check if lock is free
3 JE Get_Lock
4 JMP Spin_Lock
5 Get_Lock:
После нескольких итераций предсказатель ветвления предскажет, что условная ветвь (3) никогда не будет принята, и трубопровод будет заполняться инструкциями CMP (2). Это продолжается до тех пор, пока, наконец, другой процессор не будет записывать нуль в lockvar. На этом этапе у нас есть конвейер, полный спекулятивных (т.е. Еще не выполненных) инструкций CMP, некоторые из которых уже считывают lockvar и сообщают (неверный) ненулевой результат в следующую условную ветвь (3) (также спекулятивную). Это происходит при нарушении порядка памяти. Всякий раз, когда процессор "видит" внешнюю запись (запись от другого процессора), он ищет в своем конвейере инструкции, которые спекулятивно обращались к одному и тому же месту памяти и еще не зафиксировали. Если какие-либо такие инструкции найдены, то спекулятивное состояние процессора недействительно и стирается с помощью флеш-конвейера.
К сожалению, этот сценарий будет (очень вероятно) повторяться каждый раз, когда процессор ожидает открутить блокировку и сделает эти блокировки намного медленнее, чем они должны быть.
Введите инструкцию PAUSE:
1 Spin_Lock:
2 CMP lockvar, 0 ; Check if lock is free
3 JE Get_Lock
4 PAUSE ; Wait for memory pipeline to become empty
5 JMP Spin_Lock
6 Get_Lock:
Инструкция PAUSE будет "де-конвейерно" считывать память, так что конвейер не заполняется спекулятивными инструкциями CMP (2), как в первом примере. (Т.е. он может блокировать конвейер до тех пор, пока не будут зафиксированы все старые команды памяти.) Поскольку инструкции CMP (2) выполняются последовательно, маловероятно (т.е. временное окно намного короче), что внешняя запись происходит после того, как инструкция CMP (2) читается lockvar, но до выполнения CMP.
Конечно, "де-конвейерная обработка" также будет тратить меньше энергии на спин-замок, а в случае гиперпотока это не будет тратить ресурсы, которые другая нить могла бы использовать лучше. С другой стороны, все еще существует неправильное предсказание ветвления, ожидающее появления перед каждым выходом цикла. Документация Intel не предполагает, что PAUSE устраняет этот поток потока, но кто знает...