Ваша "длинная цепочка деп" - это много мопов из тех микрокодированных инструкций x87.fcos
- это 53-105 моп в SKL с пропускной способностью 50-130 циклов.Таким образом, это примерно 1 цикл на задержку, и планировщик / станция резервирования (RS) "только" имеет 97 записей в SKL / KBL.Кроме того, может возникнуть проблема с получением более поздних инструкций в бэкэнде вышедшего из строя, потому что микрокод берет на себя внешний интерфейс и нуждается в каком-то механизме, чтобы решить, какие мопы выпустить дальше, возможно, в зависимости от результата некоторых вычислений.(Количество мопов, как известно, зависит от данных.)
Если вы хотите наибольшую задержку из-за того, что RS полон невыполненных мопов, цепочка зависимостей sqrtpd
, вероятно, будет лучшим выбором.например,
xorps xmm0,xmm0 ; avoid subnormals that might trigger FP assists
times 40 sqrtsd xmm0, xmm0
; then make the store of the new ret addr dependent on that chain
movd ebx, xmm0
; and ebx, 0 ; not needed, sqrt(0) = 0.0 = integer bit pattern 0
mov [rsp+rbx], rax
ret
Начиная с Nehalem, процессоры Intel имеют быстрое восстановление при промахах ветвления с помощью буфера порядка ветвления, который снимает состояние OoO (включая RAT и, вероятно, RS) Что именно происходит, когда процессор Skylake неправильно прогнозируетветка? . Таким образом, они могут в точности восстановиться до ошибочного прогноза, не дожидаясь, пока ошибочный прогноз станет состоянием выхода на пенсию.
mov [rsp], rax
может выполняться сразу после его входа в RS или, по крайней мере, без зависимостив цепочке sqrt
dep.Как только переадресация магазина может выдать значение, uop ret
может выполнить и проверить прогноз, а также обнаружить неверный прогноз, пока цепочка sqrt dep все еще работает.(ret
- это 1 микроплавленый бит для портов загрузки + порт 6, где находится исполняемый модуль ветвления.)
Соединение цепочки депо sqrtsd
с сохранением нового обратного адреса предотвращаетret
с раннего выполнения . Выполнение a ret
моп в порту выполнения = проверка прогноза и обнаружение ошибочного прогноза, если таковой имеется.
(Контраст с Meltdown, где «неправильный» путь продолжается досбойная нагрузка достигает выхода на пенсию, и вы хотите выполнить ее как можно скорее (только не удаляясь). Но вы обычно хотите поставить целую атаку Meltdown в тень чего-то другого, например TSX или specpoline, в этом случаевам нужно что-то вроде этого и иметь полное падение в тени этой цепи депо . Тогда для Meltdown не понадобится собственная sqrtsd
цепочка деп.)
(vsqrtpd ymm
по-прежнему 1 моп на SKL, с худшей пропускной способностью, чем xmm, но с той же задержкой . Поэтому используйте sqrtsd
, потому что это такая же длина и, вероятно, более энергоэффективная.)
Наилучшая задержка составляет 15 циклов против наихудшего значения 16 для SKL / KBL (https://agner.org/optimize),, поэтому вряд ли имеет значение, с какого ввода вы начинаете.
Я изначально использовал sqrtpd с сиМилар результаты.Однако я не инициализировал регистр XMM, используемый как вход (и выход), думая, что это не имеет значения.Я проверил снова, но на этот раз я инициализировал регистр с двумя двойными значениями 1e200, и я получаю неустойчивый результат.Иногда строка выбирается спекулятивно, иногда это не так.
Если XMM0 содержит субнормальное значение (например, битовая комбинация представляет собой небольшое целое число), sqrtpd принимает помощь микрокода.(fp_assist.any
счетчик перфорации).Даже если результат нормальный, но вход ненормальный.Я проверил оба случая на SKL с помощью этого цикла:
pcmpeqd xmm0,xmm0
psrlq xmm0, 61 ; or 31 for a subnormal input whose sqrt is normalized
addpd xmm0,xmm0 ; avoid domain-crossing vec-int -> vec-fp weirdness
mov ecx, 10000000
.loop:
sqrtpd xmm1, xmm0
dec ecx
jnz .loop
mov eax,1
int 0x80 ; sys_exit
perf stat -etask-clock,context-switches,cpu-migrations,page-faults,cycles,branches,instructions,uops_issued.any,uops_executed.thread,fp_assist.any
показывает 1 ассистент на итерацию для ненормальных входных данных, с выданными 951M
моп (и ~ 160 циклов на итерацию).Таким образом, мы можем заключить, что вспомогательный микрокод для sqrtpd
в этом случае занимает ~ 95 моп и имеет пропускную способность ~ 160 циклов, когда это происходит спина к спине.
против.Всего выдано 20 млн. Моп для ввода = NaN (все единицы), с 4,5 циклами на итерацию.(Цикл работает 10M sqrtpd
мопс и 10 Мб с макросом dec / jcc моп.)