Как процессор предсказывает, инструкции и пределы данных в последовательности двоичной информации двоичного файла? - PullRequest
0 голосов
/ 20 февраля 2020

Как CPU отличает инструкцию от данных?

Как процессоры определяют длину команды (она варьируется от 1 до 15 байт) при выполнении кода? если предположить, что процессор не определяет длину инструкции, он может принять данные как часть инструкции. В этом случае может прийти нежелательный результат, или процессор не выполнит эту инструкцию (если не в листе кода операции). Как процессор определяет, данные это или инструкция?

1 Ответ

2 голосов
/ 20 февраля 2020

Это не должно предсказывать. Логически он декодирует один байт за раз, пока не увидит полную инструкцию. (или куски двойного слова для disp32 или imm32, или другие многобайтовые части инструкции, подразумеваемой более ранним байтом.) Длина инструкция подразумевается префиксами и байтами opcode + modrm + SIB. Посмотрев их, ЦП точно знает, сколько еще байтов инструкций ему нужно извлечь.

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

Физически в реальной реализации нет проблем спекулятивно загружать более поздние байты, если вы в конечном итоге поступайте правильно.

например, кэш инструкций L1 использует 64-байтовые строки, поэтому логическое выполнение, достигающее байта, означает, что весь 64-байтовый фрагмент памяти будет находиться в I-кэше, даже если он также в D-кеше L1, потому что вы выполняли некоторые инструкции по загрузке данных для других байтов в той же строке.

И выборка из кэша L1I тоже, конечно, не является одиночным байтом. На современном x86 декодирование просматривает блоки по 32 или 16 байт, чтобы найти границы команд. Например, давайте посмотрим на семейство P6, у которого нет кэша UOP, поэтому он всегда выбирает / декодирует из L1I.

Из микроархива Агнера Фога PDF , в PPro / PII / Раздел PIII:

6.2 Выборка инструкций

Коды команд извлекаются из кэша кодов в выровненных 16-байтовых фрагментах в двойные буфер, который может содержать два 16-байтовых блока. Цель двойного буфера состоит в том, чтобы сделать возможным декодировать инструкцию, которая пересекает 16-байтовую границу (то есть адрес, делимый на 16). Код передается из двойного буфера в декодеры в блоках, которые я буду называть блоками IFETCH (блоками выборки команд). Блоки IFETCH имеют длину до 16 байтов. В большинстве случаев блок выборки команд заставляет каждый блок IFETCH начинаться с границы инструкции, а не с 16-байтовой границы. Тем не менее, блок выборки команд нуждается в информации от декодера длины команд, чтобы знать, где находятся границы команд. Если эта информация не доступна вовремя, тогда она может начать блок IFETCH с 16-байтовой границы. Это усложнение будет обсуждаться более подробно ниже.

Затем этап конвейера предварительного декодера находит границы команд (при условии, что они все действительные команды), затем (следуя прогнозам, сделанным прогнозированием ветвлений блок) машинный код для 3-х команд отправляется на 3-х декодеров параллельно. (Core2 расширен до 4 декодеров, Skylake увеличен до 5 декодеров, хотя ширина конвейера остается на уровне 4 моп.)

Если где-то есть недопустимая инструкция (или безусловная jmp, или * jcc, что происходит), затем более поздние «инструкции» не имеют смысла и отбрасываются при обнаружении этого факта.

https://www.realworldtech.com/nehalem/5/ говорит об этапах декодирования в Nehalem, последнее поколение микроархитектур семейства P6. Но описание Агнера Фога, вероятно, более полезно с точки зрения понимания того, как процессор может смотреть на группу байтов, а затем использовать только те из них, которые должны логически выполняться как инструкции .

...