Когда uops достигают распределителя, в схеме PRF + Retirement RAT (SnB и далее), распределитель обращается к RAT внешнего интерфейса (F-RAT), когда это необходимо для переименования записей ROB (т. Е. Когда запись в архитектурный регистр ( например, rax
) выполняется) он назначается каждому uop в конце указателя ROB. RAT хранит список свободных и используемых регистров физического назначения (pdsts) в PRF. RAT возвращает свободные номера физических регистров, которые должны использоваться, а затем ROB помещает их в соответствующие записи (в схеме RRF распределитель предоставил RAT используемые pdsts; RAT не смог выбрать, потому что pdsts по сути, находились на хвостовом указателе ROB). RAT также обновляет каждый указатель архитектурного регистра с помощью назначенного ему регистра, то есть теперь он указывает на регистр, который содержит самые последние данные записи в программном порядке. В то же время ROB размещает запись на Станции бронирования (RS). В случае магазина он разместит uop адреса магазина и uop данных магазина в RS. Распределитель также выделяет записи SDB (буфер данных хранилища) / SAB (буфер адреса хранилища) и выделяет их только тогда, когда доступны все необходимые записи в ROB / RS / RAT / SDB / SAB.
Как только эти мопы выделяются в RS, RS считывает физические регистры для своих исходных операндов и сохраняет их в поле данных и в то же время проверяет шины обратной записи EU на предмет этих исходных PR (физических регистров), связанных записей ROB и данные обратной записи по мере их записи обратно в ROB. Затем RS планирует отправку этих мопов на порты store-address и store-data, когда они получат все свои завершенные исходные данные.
Затем отправляются пакеты uop - адрес хранилища uop переходит в AGU, а AGU генерирует адрес, преобразует его в линейный адрес и затем записывает результат в SAB. Я не думаю, что хранилище вообще требует PR в схеме PRF + R-RAT (это означает, что на этом этапе не требуется обратная запись в ROB), но в схеме RRF записи ROB были вынуждены использовать свои встроенный PR и все остальное (записи ROB / RS / MOB) были идентифицированы их номерами PR. Одним из преимуществ схемы PRF + R-RAT является то, что ROB и, следовательно, максимальное количество мопов в полете могут быть расширены без необходимости увеличения количества PR (поскольку будут инструкции, которые не требуют никаких), и все адресуется номерами записей ROB в случае, если записи не имеют идентифицирующих PR.
Данные магазина проходят напрямую через конвертер магазина (STC) в SDB. Как только они отправлены, они могут быть освобождены для повторного использования другими мопами. Это предотвращает ограничение гораздо большего ROB размером RS.
Затем адрес отправляется в dTLB, и он сохраняет вывод физического тега из dTLB в PAB кэша L1d.
Распределитель уже выделил SBID и соответствующие записи в SAB / SDB для этой записи ROB (мопы STA + STD микроплиты в одну запись), которые буферизуют результаты диспетчерского выполнения в AGU / TLB от RS. Магазины находятся в SAB / SDB с соответствующей записью с тем же номером записи. (SBID), который связывает их вместе, до тех пор, пока MOB не будет проинформирован отделением вывода о том, какие магазины готовы к выводу из эксплуатации, т.е. они больше не являются спекулятивными, и он не будет проинформирован о совпадении CAM указателя извлечения записи ROB, указывающего на индекс ROB / ID, который содержится в записи SAB / SDB (в uarch, который может выводить из строя 3 мопа за цикл, есть 3 указателя вывода, которые указывают на 3 самые старые неизвлекаемые инструкции в ROB, и только битовые шаблоны готовности ROB 0,0 , 1 0,1,1 и 1,1,1 разрешают поиск совпадений CAM-указателей для продолжения). На этом этапе они могут быть выведены из эксплуатации в ROB (известном как «списать / завершить локально») и стать старшими хранилищами и помечены старшим битом (бит Ae для STA, бит De для STD) и медленно отправляются в L1d. кеш, пока данные в SAB / SDB / PAB действительны.
Кэш L1d использует линейный индекс в SAB для декодирования набора в массиве тегов, который будет содержать данные с использованием линейного индекса, и в следующем цикле использует соответствующую запись PAB с тем же значением индекса, что и SBID, для сравнения физического тег с тегами в наборе. Вся цель PAB состоит в том, чтобы разрешить ранний поиск TLB для магазинов, чтобы скрыть накладные расходы на промах dTLB, пока они не делают ничего другого, ожидая, чтобы стать старшим, и разрешить спекулятивные обходы страниц, пока магазины все еще фактически спекулятивны. Если хранилище является сразу старшим, то этот ранний поиск TLB, вероятно, не происходит, и он просто отправляется, и именно тогда кеш L1d декодирует набор массивов тегов и параллельно ищет dTLB, а PAB обходится. Однако помните, что он не может выйти из ROB до тех пор, пока не будет выполнена трансляция TLB, потому что может быть код исключения PMH (ошибка страницы или чтение битов доступа / грязных битов необходимо установить при выполнении обхода страницы) или исключение код, когда TLB необходимо записать через биты доступа / грязные биты, которые он устанавливает в записи TLB. Вполне возможно, что поиск TLB для хранилища всегда происходит на этом этапе и не выполняет его параллельно с установленным декодированием (в отличие от загрузок). Хранилище становится старшим, когда PA в PAB становится действительным (действительный бит установлен в SAB), и он готов к списанию в ROB.
Затем он проверяет состояние линии. Если это общая линия, физический адрес отправляется в домен согласованности в RFO (всегда RFO для записи), и когда он владеет линией, он записывает данные в кэш. Если строка отсутствует, то для этой строки кэша выделяется LFB, и данные хранилища хранятся в нем, и запрос отправляется в L2, который затем проверяет состояние строки в L2 и инициирует чтение или RFO на кольцевой интерфейс IDI.
Хранилище становится глобально видимым, когда RFO завершается, и бит в LFB указывает, что у него есть разрешение на запись строки, что означает, что LFB будет последовательно записан обратно при следующем аннулировании или выселении отслеживания (или в случае попадания, когда данные записываются в строку). Он не считается глобально видимым, если он просто записывается в LFB до того, как происходит выборка строки в случае промаха (в отличие от старших нагрузок, которые удаляются при попадании или когда LFB отключается. выделены кешем L1d), потому что могут быть другие RFO, инициированные другими ядрами, которые могут достичь контроллера слайса LLC до запроса от текущего ядра, что было бы проблемой, если бы SFENCE
на текущем ядре был удален на основе этой версии «глобально видимого» вывода из эксплуатации - по крайней мере, это обеспечивает гарантию синхронизации для межпроцессорных прерываний. Глобально видимый - это тот самый момент, когда эти сохраненные данные будут считаны другим ядром, если нагрузка произойдет на другом ядре, а не момент, когда она будет через небольшой промежуток времени, когда до этого старое значение все еще будет считываться другими ядрами. Сохранение завершается кешем L1d после выделения LFB (или когда они записываются в строку в случае попадания) и удаляются из SAB / SDB. Когда все предыдущие хранилища удалены из SAB / SDB, именно тогда store_address_fence
(не store_address_mfence
) и связанный с ним store_data_fence
могут быть отправлены в L1d. Для LFENCE
более практично сериализовать поток инструкций ROB, тогда как _7 _ / _ 8_ этого не делать, потому что это потенциально может вызвать очень долгую задержку в ROB для глобальной видимости и не является необходимым, в отличие от старших нагрузок, которые удаляются мгновенно, поэтому имеет смысл, почему LFENCE
был выбран забором для одновременной сериализации потока инструкций. SFENCE/MFENCE
не удаляются, пока все выделенные LFB не станут глобально видимыми.
Буфер заполнения строки может находиться в одном из трех режимов: чтение, запись или объединение записи. Я думаю, что цель буфера заполнения строки записи состоит в том, чтобы объединить несколько хранилищ с данными одной строки в LFB, а затем, когда строка прибывает, заполнить недействительные биты данными, полученными из L2. Возможно, на этом этапе он считается завершенным, и поэтому записи выполняются в большом количестве и на цикл раньше, а не дожидаются их записи в строку. При условии, что теперь гарантируется запись обратно в кэш в ответ на RFO другого ядра. LFB, вероятно, останется выделенным до тех пор, пока его не нужно будет освободить, что позволит немного быстрее удовлетворить последующие операции чтения и записи в ту же строку. Буфер строки чтения может обслуживать пропуски чтения на несколько циклов быстрее, потому что он мгновенно доступен в буфере заполнения строки, но требует больше времени, чтобы записать его в строку кэша, а затем прочитать из нее. Буфер объединения записи выделяется, когда память относится к типу USWC
, и позволяет выполнять запись немедленно и сбрасывать ее на устройство MMIO сразу, вместо того, чтобы иметь несколько транзакций Core- ›PCIe и иметь несколько транзакций PCIe. Буфер WC также допускает спекулятивное чтение из буфера. Обычно спекулятивные чтения не допускаются в памяти UC, потому что чтение может изменить состояние устройства MMIO, но также чтение / запись занимает так много времени, что к тому времени, когда оно завершится, оно больше не будет спекулятивным и поэтому, возможно, не стоит дополнительных движение? LFB, скорее всего, является VIPT (VIPT / PIPT такие же на intel, а V - линейный адрес на intel); Я предполагаю, что у него может быть физический и виртуальный теги, чтобы исключить дальнейшие поиски TLB, но ему придется что-то согласовывать, когда физическая страница мигрирует на новый физический адрес.
person
Lewis Kelsey
schedule
26.01.2021