Относительно упорядочения команд при выполнении загрузок с пропуском кеша до хранения кеша на x86 - PullRequest
2 голосов
/ 10 мая 2019

Учитывая небольшую программу, показанную ниже (созданную вручную, чтобы выглядеть одинаково с точки зрения последовательной согласованности / TSO), и предполагая, что она выполняется суперскалярным неупорядоченным процессором x86:

Load A <-- A in main memory
Load B <-- B is in L2
Store C, 123 <-- C is L1

У меня есть несколько вопросов:

  1. Если предположить, что окно инструкций достаточно большое, будут ли три инструкции извлечены, декодированы и выполнены одновременно? Я предполагаю, что нет, так как это нарушит выполнение программы.
  2. 2-ая загрузка займет больше времени, чтобы извлечь A из памяти, чем B. Придется ли последнему ждать, пока первая будет полностью выполнена? Будет ли выборка B начинаться только после полного выполнения загрузки A? или до чего ждать?
  3. Зачем магазину ждать грузов? Если да, будет ли инструкция просто ждать фиксации в буфере хранилища до окончания загрузки или после декодирования, ей придется сидеть и ждать загрузки?

Спасибо

1 Ответ

3 голосов
/ 10 мая 2019

Терминология: «окно команд» обычно означает окно выполнения вне очереди, через которое ЦП может найти ILP. то есть размер ROB или RS. См. Понимание влияния lfence на цикл с двумя длинными цепочками зависимостей, для увеличения длины

Термин «сколько инструкций может пройти через конвейер за один цикл» - это конвейер ширина . например Скайлэйк является суперскалярным из 4 в ширину. (Части его конвейера, такие как декодирование, выборка из uop-кэша и удаление, шире, чем 4 мопа, но узкая точка выпуска / переименования.)


Терминология: « ожидает принятия в буфере хранилища » данные хранилища + адрес записываются в буфер хранилища при выполнении хранилища. фиксирует из буфера хранения в L1d в любой момент после выхода на пенсию, когда известно, что он не является спекулятивным.

(В программном порядке, чтобы поддерживать модель памяти TSO без переупорядочения хранилища. Буфер хранилища позволяет хранилищам выполнять внутри этого ядра не в порядке, но по-прежнему принимать L1d (и стать глобально). visible) по порядку. Выполнение хранилища = запись адреса + данных в буфер хранилища. )
Что такое буфер хранилища?
Размер буферов магазина на оборудовании Intel? Что именно является буфером хранилища?


Внешний интерфейс не имеет значения . 3 последовательных инструкции могут быть извлечены в одном и том же 16-байтовом блоке выборки и могут пройти предварительное декодирование и декодирование в том же цикле, что и группа. И (также или вместо) выпускать в неработающий сервер как часть группы из 3 или 4 мопов. IDK, почему вы думаете, что это может вызвать потенциальную проблему.

Внешний интерфейс (от выборки к выпуску / переименованию) обрабатывает инструкции в программном порядке. Обработка одновременно не помещает более поздние инструкции перед более ранними, она помещает их в то же самое время . И что еще более важно, он сохраняет информацию о том, каков порядок программ; это не потеряно и не отброшено, потому что это важно для инструкций, которые зависят от предыдущего 1 !

Между большинством этапов конвейера существуют очереди, поэтому (например, в Intel Sandybridge) инструкции, которые предварительно декодируют как часть группы из 6 команд, могут не попадать в декодеры как часть той же группы восходящего потока. к-4 (или больше с макро-синтезом). См. https://www.realworldtech.com/sandy-bridge/3/ для получения и следующую страницу для декодирования. (И кеш моп.)


Выполнение (отправка мопов на порты исполнения из планировщика с нарушением порядка) - вот где порядок имеет значение. Планировщик не по порядку должен избегать взлома однопоточного кода. 2

Обычно выпуск / переименование намного опережают выполнение, если только вы не являетесь узким местом в интерфейсе. Поэтому обычно нет оснований ожидать, что выпущенные вместе мопы будут выполняться вместе. (Ради аргумента, давайте предположим, что 2 загрузки, которые вы показываете, отправляются для выполнения в одном и том же цикле, независимо от того, как они попали туда через интерфейс.)

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

2) [порядок загрузки]

Это сложная часть.

Как я объяснил в ответе + комментарии к вашему последнему вопросу , современные процессоры x86 будут умозрительно использовать результат попадания L2 от Load B для более поздних инструкций, даже если модель памяти требует, чтобы эта загрузка происходила после загрузки A.

Но если никакие другие ядра не пишут в строку кэша B до завершения загрузки A, то ничто не может отличить. Буфер порядка памяти заботится об обнаружении недействительных строк кэша, которые были загружены ранее.загрузка завершена, и выполняется очистка конвейера неверной спекуляции порядка памяти (откат до состояния выхода из строя) в редком случае, когда изменение порядка загрузки может изменить результат.

3) Почему магазинприходится ждать загрузки?

Не будет, если только адрес хранилища не зависит от значения нагрузки. Планировщик uop отправит адрес хранилища и адрес хранилища.данные переходят к исполнительным блокам, когда их входные данные готовы.

Это после загрузок в программном порядке, и буфер хранения сделает его еще дальше после загрузок, насколько это касается глобального порядка памяти. Буфер хранилища не будет фиксировать данные хранилища в L1d (делая их глобально видимыми) до тех пор, пока хранилище не будет удалено.Так как это после нагрузок, они также будут удалены.

( Выход на пенсию в порядке , чтобы разрешить точные исключения и убедиться, что предыдущие инструкции не занялиисключение или ошибочно предсказанная ветвь. Порядок вывода из строя позволяет нам с уверенностью сказать, что инструкция не является спекулятивной после ее выхода из системы.)

Так что да, этот механизм гарантирует, что хранилище не сможет зафиксироватьдо L1d до тех пор, пока обе нагрузки не заберут данные из памяти (через кэш L1d, который обеспечивает согласованное представление памяти всем ядрам).Таким образом, это предотвращает переупорядочение LoadStore (более ранних загрузок с более поздними хранилищами).

Я не уверен, что какие-либо слабо упорядоченные OoO-процессоры выполняют переупорядочивание LoadStore.Это возможно на процессорах обычного порядка, когда загрузка с отсутствием кэша предшествует хранилищу попаданий в кэш, и процессор использует табло, чтобы избежать остановки до тех пор, пока данные о нагрузке фактически не будут считаны из регистра, если он все еще не готов.(LoadStore странный: см. Также барьеры памяти Джеффа Прешинга как операции управления исходным кодом ).Может быть, некоторые OoO exec-процессоры также могут отслеживать отставку хранилищ кэша, когда они, как известно, определенно происходят, но данные просто еще не поступили.x86 не делает этого, потому что это нарушит модель памяти TSO.


Сноска 1: Существуют некоторые архитектуры (обычно VLIW), в которых пакеты одновременных инструкций являются частьюархитектура таким образом, чтобы это было видно для программного обеспечения.Поэтому, если программное обеспечение не может заполнить все 3 слота инструкциями, которые могут выполняться одновременно, оно должно заполнить их NOP.Может даже быть разрешено поменять 2 регистра с пакетом, который содержал mov r0, r1 и mov r1, r0, в зависимости от того, позволяет ли ISA инструкции в одном и том же пакете читать и записывать одни и те же регистры.

Но x86не так: суперскалярное неупорядоченное выполнение всегда должно сохранять иллюзию выполнения инструкций по одному в программном порядке. Кардинальное правило OoO exec: не нарушать однопоточный код.

Все, что может нарушить это, может быть сделано только с проверкой на опасность илиспекулятивно с откатом при обнаружении ошибок.

Сноска 2: (продолжение со сноски 1)

Вы можете извлекать / декодировать / выдавать два спина к спине inc eax инструкции, но они не могут выполняться в одном и том же цикле, потому что переименование регистра + планировщик OoO должен обнаружить, что 2-й считывает выходные данные первого.

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