Где находится объединяющий запись буфер? x86

Как физически подключается буфер Write-Combine? Я видел блок-схемы, иллюстрирующие ряд вариантов:

  • Между L1 и контроллером памяти
  • Между буфером хранения ЦП и контроллером памяти
  • Между процессорами AGU и / или хранилищами

Это зависит от микроархитектуры?

2 ответа

Решение

Буферы записи могут иметь разные цели или различное использование в разных процессорах. Этот ответ может не относиться к процессорам, не упомянутым специально. Я хотел бы подчеркнуть, что термин "буфер записи" может означать разные вещи в разных контекстах. Этот ответ касается только процессоров Intel и AMD.

Объединяющие записи буферы на процессорах Intel

Каждый кеш может сопровождаться нулем или более буферов заполнения строки (также называемых буферами заполнения). Коллекция буферов заполнения в L2 называется супер-очередью или супер-очередью (каждая запись в супер-очереди является буфером заполнения). Если кэш разделен между логическими ядрами или физическими ядрами, то соответствующие буферы заполнения также распределяются между ядрами. Каждый заполняющий буфер может содержать одну строку кэша и дополнительную информацию, которая описывает строку кэша (если она занята), включая адрес строки кэша, тип памяти и набор битов достоверности, где количество битов зависит от степени детализации отслеживание отдельных байтов строки кэша. В ранних процессорах (таких как Pentium II) только один из буферов заполнения способен объединять записи (и свернуть записи). Общее количество строковых буферов и тех, которые способны к комбинированию записи, постоянно увеличивается с новыми процессорами. Последние процессоры Intel включают 10 заполняющих буферов в каждый кэш данных L1, каждый из которых может объединять записи (не путать с определенным типом памяти, сочетающим запись (WC)). Создание буфера заполнения, способного к комбинированию записи, требует дополнительного оборудования (не только для включения объединения записи, но и для поддержания порядка хранения в памяти для строго упорядоченных типов памяти), поэтому такая функция не предоставляется бесплатно.

Буфер заполнения строки используется в нескольких сценариях:

  • Буфер заполнения выделяется при загрузке (запрос или предварительная выборка) или при отсутствии сохранения в кэше. Если не было доступного буфера заполнения, запросы на загрузку и сохранение продолжают накапливаться в буферах загрузки и хранения, что может в конечном итоге привести к зависанию внешнего интерфейса. В случае запроса загрузки выделенный буфер заполнения используется для временного хранения запрошенных строк с более низких уровней иерархии памяти, пока они не могут быть записаны в массив данных кэша. Но запрошенная часть строки кэша все еще может быть предоставлена ​​в регистр назначения, даже если строка еще не была записана в массив данных кэша. Сами запросы на загрузку / сохранение, которые запрашивали строку кэша (может быть несколько запросов для одной и той же строки), хранятся в отдельной аппаратной структуре. В случае запроса на сохранение данные, которые должны быть сохранены (которые могут быть меньше, чем размер строки кэша), хранятся в буфере заполнения строки. Сам кеш имеет только один действительный бит на строку кеша, поэтому все байты строки кеша должны быть действительными, или ни один из них не является действительным. Но в буфере заполнения может быть действительный бит для каждого байта строки кэша. Это означает, что операция сохранения не может быть выполнена в кэше, пока все байты не будут действительными. Это может потребовать ожидания получения целевой строки кэша от остальной части иерархии памяти. Пока это не произойдет, строковый буфер может быть отслежен для дальнейших запросов на загрузку. Когда это происходит, байты, измененные запросом сохранения, объединяются с целевой строкой кэша, и затем эта строка может быть записана в кэш. Во время всей этой операции линия должна быть в состоянии "Модифицировано / Владелец" (или, точнее, в некотором промежуточном состоянии, в зависимости от протокола), чтобы поддерживать согласованность. Заполняющие буферы уменьшают эффективное влияние промахов на общую производительность.
  • Заполняющий буфер может использоваться для объединения и / или свертывания байтов нескольких запросов на сохранение в одну и ту же строку, но только если тип памяти целевой области памяти позволяет это. Такое поведение может влиять на порядок записи, видимой для некогерентных агентов (таких как устройства ввода-вывода). Буферы заполнения строки, используемые как буферы объединения записи, могут быть сброшены разными способами, например, при выполнении SFENCE, MFENCEили инструкция сериализации.
  • Некоторым типам запросов памяти не разрешается кэшироваться (невременные запросы), но, тем не менее, строковые буферы могут по-прежнему использоваться для выполнения запросов для повышения производительности. Все уровни кэшей и буферов могут быть обойдены между контроллером памяти и выделенным буфером заполнения строки. Есть некоторые процессоры AMD, которые используют буферы, которые отделены от буферов заполнения для невременных хранилищ. Также было несколько буферов WCB в P6 (первый, чтобы реализовать WCB) и P4, выделенных для типа памяти WC (не может использоваться для других типов памяти). В ранних версиях P4 таких буферов было 4. Для версий P4, которые поддерживают гиперпоточность, когда включена гиперпоточность и оба логических ядра работают, WCB статически распределяются между двумя логическими ядрами. Современные микроархитектуры Intel, тем не менее, конкурируют между собой всеми LFB, но оставляют по крайней мере по одному доступному для каждого логического ядра, чтобы предотвратить голодание.

Буферы заполнения управляются контроллером кэша, который подключен к другим контроллерам кэша на других уровнях (или контроллеру памяти в случае LLC). Заполняющий буфер не выделяется, когда запрос попадает в кеш. Таким образом, запрос хранилища, который попадает в кеш, выполняется непосредственно в кэше, а запросы на загрузку, которые попадают в кеш, обслуживаются непосредственно из кэша. Заполняющий буфер может не выделяться, когда строка выгружается из кэша, в зависимости от конструкции. Выселения либо записываются в свои собственные буферы (называемые буферами обратной записи или буферами вытеснения), записываются в буферы кэша следующего уровня или записываются непосредственно в кэш следующего уровня. Вообще, пространство дизайна действительно огромно. К сожалению, в академических кругах не так много исследований по заполнению буферов, и компании-производители процессоров обсуждают их в своих патентах. Например, вот патент от Intel, который обсуждает расчесывание записи для операций ввода-вывода. Поэтому трудно быть точным, обсуждая их.

Объединяющие записи буферы на процессорах AMD

Я уже упоминал в соответствии со статьей, что есть некоторые процессоры AMD, которые используют буферы, которые отделены от буферов заполнения для невременных хранилищ. Я цитирую из статьи:

На более старых процессорах AMD (K8 и Family 10h) невременные хранилища использовали набор из четырех "регистров объединения записи", которые не зависели от восьми буферов, используемых для ошибок кэша данных L1.

Часть "на старых процессорах AMD" заинтересовала меня. Изменилось ли это на более новых процессорах AMD? Мне кажется, что это все еще верно для всех новых процессоров AMD, включая самые последние процессоры семейства 17h (Zen). Статья WikiChip по миркоархитектуре Zen включает в себя две фигуры, которые упоминают буферы WC: это и это. На первом рисунке непонятно, как используются WCB. Однако во втором ясно, что показанные WCB действительно специально используются для записи NT (нет связи между WCB и кешем данных L1). Источник для второго рисунка, кажется, эти слайды1. Я думаю, что первый рисунок был сделан WikiChip (который объясняет, почему WCB были помещены в неопределенную позицию). На самом деле, статья WikiChip ничего не говорит о WCB. Но тем не менее, мы можем подтвердить, что показанные WCB используются только для записи NT, взглянув на рис. 7 из Руководства по оптимизации программного обеспечения для процессоров AMD 17-го семейства и патента на очереди загрузки и хранения для процессоров семейства 17-го. В руководстве по оптимизации AMD говорится, что в современных процессорах AMD имеется 4 WCB на ядро. Я думаю, что это относится к K8 и всем последующим процессорам. К сожалению, ничего не сказано о буферах AMD, которые играют роль буферов заполнения Intel.


(1) Майкл Кларк, новый высокопроизводительный процессор x86 Core от AMD, 2016.

В современных процессорах Intel объединение записи выполняется с помощью LFB (line-fill-buffers), также используемых для других ожидающих передач из L1 <-> L2. Каждое ядро ​​имеет 10 из них (начиная с Nehalem). ( Передачи между L2 и L3 используют разные буферы, которые называются "супер очереди").

Вот почему Intel рекомендует избегать слишком большого количества другого трафика при работе с хранилищами NT, чтобы избежать ранних сбросов частично заполненных LFB, вызванных распределением нагрузок по требованию. https://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffers

"Внутри" LFB есть соединения с L1d, буфером хранения и портами загрузки.

"Внешние" LFB могут общаться с L2 или (возможно, с помощью L2) переходить через кольцевую шину / сетку к контроллерам памяти или L3 для предварительной выборки NT. Выход из ядра, вероятно, не сильно отличается для L3 и памяти; просто другой тип сообщения для отправки по кольцевому / сеточному соединению между ядрами; в процессорах Intel контроллеры памяти являются еще одной остановкой на кольцевой шине (в "системном агенте"), как и другие ядра с их частями L3. @BeeOnRope предполагает, что LFB L1 на самом деле не подключены напрямую к кольцевой шине, и запросы, которые не помещают данные в L2, вероятно, все еще проходят через буферы супер очереди L2 к кольцевой шине / мешу. Это кажется вероятным, поэтому каждому ядру нужна только одна точка присутствия на кольцевой шине и арбитраж для него между L2 и L1 происходит внутри ядра.


Данные хранилища NT поступают в LFB непосредственно из буфера хранилища, а также проверяют L1d, чтобы выяснить, нужно ли сначала удалить эту строку.

Нормальные данные хранилища поступают в LFB, когда их выселяют из L1d, чтобы освободить место для новой выделенной строки или в ответ на RFO от другого ядра, которое хочет прочитать эту строку.

Обычные нагрузки (и хранилища), которые отсутствуют в L1d, нуждаются в кеше для извлечения этой строки, который также выделяет LFB для отслеживания входящей линии (и запроса к L2). Когда данные поступают, они отправляются прямо в буфер загрузки, который их ждет, параллельно с размещением их в L1d. (В терминах архитектуры ЦП см. "Ранний перезапуск" и "сначала критическое слово": пропуск кеша блокируется только до тех пор, пока не поступят необходимые данные, остальная часть строки кеша поступает "в фоновом режиме".) Вы (и архитекторы ЦП в Intel) определенно не хочет, чтобы задержка попадания L2 включала размещение данных в L1d и их возврат обратно.

NT загружается из памяти WC ( movntdqa ) читать прямо с LFB; данные никогда не попадают в кеш вообще. У LFB уже есть соединение для загрузки портов для раннего перезапуска обычных нагрузок, поэтому SSE4 смог добавить movntdqa я думаю, без особых затрат на кремний. Особенность в том, что промах заполнит только LFB непосредственно из памяти, минуя L3/L2/L1. Для хранилищ NT уже нужны LFB, чтобы иметь возможность общаться с контроллерами памяти.

В этом патенте говорится, что буфер WC - это действительно любой буфер заполнения строки, помеченный как "WC".

В предпочтительном в настоящее время варианте осуществления используется структура, которая уже существует в микропроцессоре архитектуры Intel™ - буферы заполнения. Буферы заполнения представляют собой набор из нескольких строк кэша с допустимыми и грязными битами с байтовой гранулярностью, которые используются микропроцессором, работающим вне очереди, для создания неблокирующего кеша. Буфер WC - это одиночный буфер заполнения, отмеченный для разрешения объединения хранилищ WC. При вытеснении буфер заполнения WC ожидает полного вытеснения буфера заполнения. В предпочтительном в настоящее время варианте осуществления реализован только один буфер объединения записи. Физически любой буфер заполнения может использоваться в качестве буфера объединения записи. Поскольку предоставляется только один буфер объединения логической записи, когда требуется второй буфер объединения записи, инициируется процесс исключения.

Далее говорится, что буфер WC может быть как типа WB, так и типа USWC. Здесь можно было бы использовать буфер комбинирования записи для обозначения "буфера заполнения строки", но я так не думаю, потому что в предложении перед этим он использует его для ссылки на буфер WC.

Это наводит меня на мысль, что WC не говорит о памяти USWC, а просто WC является свойством буфера заполнения строки. В этом случае я бы предположил, что он говорит, что один LFB может использоваться для объединения записей из буфера хранилища (который может быть типа WB или, возможно, USWC), но другие LFB используются для выселения, предварительной выборки и т. Д. Между L1 и L2 и не допускайте попадания в магазины.

В руководстве по оптимизации x86-64 говорится: "Буферы объединения записи используются для хранилищ всех типов памяти" и "Начиная с кодового имени микроархитектуры Intel Nehalem, имеется 10 буферов, доступных для объединения записи". Мы знаем, что nehalem имеет 10 LFB, поэтому это говорит мне, что все 10 могут быть помечены как WC, как показано на рисунке 3 патента (который просто описывает сценарий, в котором только один LFB может быть буфером WC за раз).

В нем также говорится: "При промахе записи в кэш первого уровня это позволяет множеству сохранений в одной строке кэша, прежде чем эта строка кеша будет считана для владения (RFO) из более отдаленных частей иерархии кеша / памяти. Затем считывается остальная часть строки, и незаписанные байты объединяются с неизмененными байтами в возвращенной строке. Когда происходит запись в буфер объединения записи для ранее незаписанной строки кэша, происходит чтение для владения (RFO). Если последующая запись происходит в другой буфер объединения записи, для этой строки кэша может быть вызван отдельный RFO. Последующие записи в первую строку кэша и буфер объединения записи будут отложены до тех пор, пока не будет обработан второй RFO, чтобы гарантировать должным образом упорядоченную видимость записей. Если тип памяти для записи - объединение записи,RFO не будет, так как строка не кэшируется, и такой задержки нет ".

Буфер объединения записи, по-видимому, является особым вариантом использования LFB, который используется для объединения записей во время выполнения RFO (*), чтобы можно было заполнить хранилища и освободить записи буфера хранилища (возможно, несколько, если все они записывают в ту же строку кэша). Действительные биты указывают биты, которые необходимо объединить в строку кэша, когда она перейдет в состояние E. Моя интерпретация следующей части состоит в том, что если происходит запись во вторую строку кэша, то для повторной записи в первую строку необходимо дождаться, пока 1-й и 2-й LFB не будут записаны (последовательно) в кеш L1d. Это необходимо для поддержания правильного порядка глобальной видимости записей. Я предполагаю, что LFB выгружается в кеш, как только строка присутствует в кеше, и все записи в строку после этого записываются непосредственно в строку кеша..

Если тип памяти - USWC, RFO не требуется, но записи в любом случае распределяются в буфер.

Поскольку PAT работают с виртуальными адресами, может возникнуть псевдоним. Т.е. одна и та же физическая страница может иметь несколько разных политик кеширования. Если потоковое хранилище (означает, что код операции записи USWC WCiL(F)) попадает в кэш L3, он вызывает QPI WBMtoI этой строки, отправляя его правильному домашнему агенту на основе правил чередования SAD, прежде чем хранилище USWC может появиться. Предположительно, кеш L1/L2 также делает это при прохождении хранилища, хотя L3 может быть оставлен для удаления и обратной записи строки, если только одно ядро ​​имеет копию. Что касается нагрузок USWC, я вообще не знаю. Кажется, что для этого нет отдельного кода операции, поэтому он может установить флаг в запросе DRd, чтобы указать, что это не временная нагрузка. Я'Я не уверен, может ли кэш L3 пересылать строки кэша с псевдонимами на запрос чтения USWC или они должны быть записаны обратно, а запрос чтения должен быть удовлетворен из DRAM (я говорю DRAM, но у контроллера памяти также, вероятно, есть хранилище для загрузки механизм переадресации, так сказать домашний агент)

Я не уверен, как работают хранилища / загрузки "вневременной подсказки". В руководстве Intel Volume 1, кажется, говорится, что подсказка в буфере хранилища заставляет все хранилища, кроме WP и UC (-), интерпретироваться контроллером L1d как USWC, тогда как подсказка не меняет политику для нагрузок, т.е. ничего не делает.. Может быть, подсказка имеет дополнительное преимущество в буфере хранилища. Планировщик памяти не знает политику кэширования загрузки / сохранения до тех пор, пока данные не будут возвращены контроллером L1d, поэтому подсказка сообщает ему, что применяется слабый порядок, и их можно отправлять более эффективно; Я думаю, что невременные записи можно переупорядочить с другими записями.

(*) Я не знаю, приводит ли запрос S->E к выделению буфера заполнения строки для записи или его можно немедленно записать в кеш. Я собираюсь сказать, что он выделяет LFB, потому что он может потерять эти данные, если временно сохранит их в строке кеша при отправке запроса S->E, потому что сначала может прийти недействительный запрос от L3 в ответ на другое ядро. Я говорю запрос S->E, потому что не знаю, как это называется. Он может быть инкапсулирован как пакет RFO, но с флагом, указывающим, что чтение не требуется, или это может быть так называемый ItoM, который имеет противоречивые определения. Некоторые источники называют это RFO, но предполагается полная запись строки кэша, что означает, что кеш не нужно читать, если он находится в состоянии I. Это также может быть использовано для переходов S->E.Вместо того, чтобы называться S/I->E, он называется ItoM, чтобы указать намерение писать в строку, но я не знаю, почему ItoE также не означал бы это. Как ни странно, на самом деле существует 2 разных кода операций UPI для согласованности кеш-памяти с несколькими сокетами, InvItoE и InvItoM, оба с одним и тем же исключением описания, последнее добавление `` с намерением выполнить обратную запись вскоре после этого ''

Другие вопросы по тегам