Какие инструкции могут привести к ошибочному прогнозированию веток на процессорах x86? - PullRequest
3 голосов
/ 16 января 2020

У меня есть тестовый вопрос здесь.

Какие инструкции могут потенциально замедлить работу процессора, тогда конвейер не предсказывает (прогноз ветвления) дальнейший способ выполнения?

Возможные ответы: JGE | ДОБАВИТЬ | SUB | PU SH | JMP | JNZ | MUL | JG | ЗВОНИТЕ

Если мы говорим о предсказании ветвления, то есть JGE, JMP, JNZ & JG - путь к go?

1 Ответ

5 голосов
/ 21 января 2020

Инструкции типа mul, которые не делают ничего особенного для EIP , конечно, не могут ошибочно предсказать, но каждый вид прыжка / вызова / ответвления может ошибочно предсказать для некоторых Степень в конвейерной конструкции, даже простой call rel32. Эффекты могут быть серьезными в сильно конвейерном, не по порядку, исполнении, как современные процессоры x86.

Да, jcc условные ветви всегда нуждаются в прогнозировании; значение FLAGS недоступно при декодировании, только позже при выполнении.

Даже прямой jmp rel8 / jmp rel32call rel32) требует прогнозирования на ранних этапах конец, прежде чем они даже будут декодированы, , поэтому этап выборки знает, какой блок следует извлечь следующим после выборки блока, который может включать или не включать переход (безусловный или предсказанный-принятый условный; он не нужен знать, стоит ли продолжать извлекать по прямой или нет). См. Медленная jmp-инструкция для получения дополнительной информации о простых безусловных прямых ветвях, работающих медленнее, если у вас слишком много для BTB.

Если вы рассматриваете простой конвейер порядка, такой как classi c 5-ступенчатая RIS C, без буферов между этапами, все ветви в основном эквивалентны: этап выборки должен получать 1 инструкцию за такт, чтобы избежать появления пузырей. Он должен знать адрес следующей выборки, в то время как предыдущая инструкция все еще декодирует. Более длинные конвейеры делают эту проблему еще хуже.


Но проще: есть косвенные формы jmp и call, такие как jmp eax или jmp [edi], которые загружают новый EIP из регистр или память . Те явно нуждаются в предсказании; у вас есть неограниченные возможности для того, где он будет go, а не только взятым или не взятым.

Ветви, которые зависят от данных (условно от FLAGS или косвенно от регистра или памяти), могут попасть в back-end (и выполнить не по порядку) до того, как будет обнаружен неправильный прогноз. Восстановление может потребовать отмены результатов выполнения более поздних инструкций с неверного пути, а также извлечения / декодирования правильного пути. Что именно происходит, когда процессор Skylake неверно предсказывает ветвь?

Но обработка ошибочных прогнозов прямого jmp / call проще: просто перенаправьте этапы выборки / декодирования, поскольку целевой адрес известен после расшифровка инструкции без необходимости ее выполнения. Неправильное предсказание не превращает его в бэкэнд, так что это «просто» пузырь во фронтэнде.


Забавный факт: ret также может ошибочно прогнозировать; это в основном косвенная ветвь (pop eip). Но есть специальные предикторы, которые используют преимущества обычного спаривания между командами call и ret, сохраняя внутренний стек недавних вызовов, который отражает, как, вероятно, будет использоваться стек вызовов в памяти. http://blog.stuffedcow.net/2018/04/ras-microbenchmarks/

...