Размер буферов магазина на оборудовании Intel? Что именно является буфером магазина?
В руководстве по оптимизации Intel говорится о количестве буферов хранилища, которые существуют во многих частях процессора, но, похоже, не говорится о размере буферов хранилища. Является ли это общедоступной информацией или размер буфера хранилища сохраняется как микроархитектурная деталь?
Процессоры, на которые я обращаю внимание, это, прежде всего, Broadwell и Skylake, но информация о других тоже была бы интересной.
Кроме того, что именно делают буферы магазина?
1 ответ
Буфер хранилища в целом состоит из нескольких записей.
Каждое ядро имеет свой собственный буфер хранения 1, чтобы отделить выполнение и удаление из фиксации в кэш L1d. Даже обычный процессор получает выгоду от буфера хранилища, чтобы избежать зависания в хранилищах с отсутствием кэша, потому что в отличие от нагрузок, они просто должны со временем стать видимыми. (Ни один из практических процессоров не использует модель памяти с последовательной последовательностью, поэтому, по крайней мере, переупорядочение StoreLoad разрешено, даже в x86 и SPARC-TSO). Для спекулятивных / вышедших из строя процессоров это также дает возможность откатить хранилище после обнаружения исключения или неправильной спекуляции в более старой инструкции, при этом спекулятивные хранилища никогда не будут видны глобально. Это очевидно важно для правильности!
Когда оба логических ядра активны (гиперпоточность), Intel разделяет буфер хранилища на два; каждое логическое ядро получает половину. Загрузка из одного логического ядра отслеживает только свою половину буфера хранилища 2. Что будет использоваться для обмена данными между потоками, выполняющимися на одном ядре с HT?
Буфер хранилища фиксирует данные из удаленных инструкций хранилища в L1d настолько быстро, насколько это возможно, в программном порядке (в соответствии со строго упорядоченной моделью памяти x86 3). Требование о том, чтобы магазины фиксировались при выходе на пенсию, излишне блокировало бы отставку для магазинов с отсутствием кэша. Запасные хранилища, все еще находящиеся в буфере хранилища, определенно произойдут, и их нельзя будет откатить, поэтому они действительно могут снизить задержку прерывания. (Прерывания технически не требуются для сериализации, но любые хранилища, созданные обработчиком IRQ, не могут стать видимыми до тех пор, пока существующие ожидающие хранилища не будут удалены. iret
является сериализацией, поэтому даже в лучшем случае буфер хранилища истощается перед возвратом.)
Это распространенное (?) Заблуждение, что его необходимо явно сбросить, чтобы данные стали видны другим потокам. Барьеры памяти не приводят к тому, что буфер хранилища сбрасывается, полные барьеры заставляют текущее ядро ждать, пока буфер хранилища не опустошится, прежде чем произойдет какая-либо последующая загрузка (т. Е. Прочитайте L1d). Операции Atomic RMW должны ждать, пока буфер хранилища опустошится, прежде чем они смогут заблокировать строку кэша и выполнить как загрузку, так и сохранение в этой строке, не позволяя ему выйти из состояния MESI Modified, что не позволит любому другому агенту в системе наблюдать его во время атомная операция.
Чтобы реализовать строго упорядоченную модель памяти x86, в то же время микроархитектурно допуская ранние / неупорядоченные загрузки (и более позднюю проверку того, что данные все еще действительны, когда разрешена архитектурная нагрузка), загрузите буфер + сохраните записи буфера вместе, образуя порядок памяти Буфер (MOB). (Если строка кеша все еще не присутствует, когда разрешено происходить загрузке, это неправильное предположение порядка памяти.) Эта структура, вероятно, где mfence
а также lock
Команды ed могут поставить барьер, который блокирует переупорядочение StoreLoad, не блокируя неупорядоченное выполнение. (Хотя mfence
на Skylake блокирует выполнение OoO независимых инструкций ALU, как детали реализации.)
movnt
магазины в обход кеша (вроде movntps
) также проходят через буфер хранилища, так что они могут рассматриваться как спекулятивные, как и все остальное в исполнительном процессоре OoO. Но они фиксируются непосредственно в LFB (Line Fill Buffer), он же буфер объединения записи, а не в кэш L1d.
Сохранение инструкций для процессоров Intel, декодируемых для хранения адресов хранения и хранения данных (микросинтеграция в один объединенный домен). Хранение-адрес uop просто записывает адрес (и, вероятно, ширину хранилища) в буфер хранилища, поэтому при последующих загрузках можно настроить пересылку store->load или обнаружить, что они не перекрываются. Хранение данных UOP записывает данные.
Store-address и store-data могут выполняться в любом порядке, в зависимости от того, что готово в первую очередь: этап выделения / переименования, который записывает мопы из внешнего интерфейса в ROB, а RS во внутреннем конце также выделяет буфер загрузки или сохранения для загрузки или хранить мопы во время выдачи. Или глохнет, пока один не доступен. Поскольку распределение и фиксация происходят по порядку, это, вероятно, означает, что более старый / младший легко отслеживать, поскольку это может быть просто циклический буфер, который не должен беспокоиться о старых долгоживущих записях, которые все еще используются после переноса. (Если только обходные / слабо упорядоченные хранилища NT не могут это сделать? Они могут фиксировать LFB (Line Fill Buffer) не по порядку. В отличие от обычных хранилищ, они передают непосредственно в LFB для передачи вне ядра, а не в L1d.)
но каков размер записи?
Размеры буфера хранилища измеряются в записях, а не в битах.
Узкие хранилища не "используют меньше места" в буфере хранилища, они все еще используют ровно 1 запись.
В буфере хранилища Skylake есть 56 записей ( википедия), по сравнению с 42 в Haswell/Broadwell и 36 в SnB/IvB (рецензия Дэвида Кантера на HSW для RealWorldTech содержит диаграммы). Вы можете найти числа для более ранних версий x86 в рецензиях Кантера на RWT, на диаграммах Викичипа или в различных других источниках.
В SKL/BDW/HSW также есть 72 записи буфера загрузки, в SnB / IvB - 64. Это количество инструкций загрузки в полете, которые либо не выполнялись, либо ожидают поступления данных из внешних кэшей.
Размер в битах каждой записи - это деталь реализации, которая никак не влияет на то, как вы оптимизируете программное обеспечение. Точно так же мы не знаем размер в битах UOP (во внешнем интерфейсе, в ROB, в RS), или детали реализации TLB, или многие другие вещи, но мы знаем, сколько ROB и RS Есть записи, и сколько записей TLB разных типов существует в различных статьях.
Корпорация Intel не публикует принципиальные схемы для своих конструкций ЦП, и (AFAIK) эти размеры обычно не известны, поэтому мы даже не можем удовлетворить наше любопытство по поводу деталей конструкции / компромиссов.
Запишите объединение в буфере магазина:
Узкие хранилища в одну и ту же строку к одной и той же строке кэша (вероятно?) Можно объединить, то есть объединить в буфере хранилища перед их фиксацией, поэтому для фиксации нескольких хранилищ может потребоваться всего один цикл на порте записи кэша L1d.
Мы точно знаем, что некоторые процессоры, отличные от x86, делают это, и у нас есть некоторые доказательства / основания полагать, что процессоры Intel действительно делают это. Но это ограничено. См. Обсуждение, начинающееся с этого комментария: Используются ли буферы объединения записи для обычной записи в области памяти WB на Intel?
А также неожиданно плохая и странно бимодальная производительность для цикла хранения на Intel Skylake может иметь значение.
Мы точно знаем, что некоторые слабо упорядоченные ISA, такие как Alpha 21264, хранили слияние в своем буфере хранения, потому что руководство документирует его вместе с его ограничениями относительно того, что он может фиксировать и / или читать в / из L1d за цикл. Также PowerPC RS64-II и RS64-III, с меньшим количеством деталей, в документах, связанных с комментарием здесь: Есть ли какие-либо современные / древние процессоры / микроконтроллеры, где кэшированное хранилище байтов на самом деле медленнее, чем хранилище слов?
Люди опубликовали статьи о том, как сделать (более агрессивным?) Объединение магазинов в моделях памяти TSO (например, x86), например, не спекулятивное объединение магазинов в общем порядке магазинов.
Объединение может позволить освободить запись в буфере хранилища до того, как его данные передадут в L1d (предположительно, только после удаления), если его данные будут скопированы в хранилище в той же строке. Это может произойти только в том случае, если никакие хранилища с другими строками не разделяют их, иначе это приведет к тому, что хранилища будут зафиксированы (станут глобально видимыми) не по порядку программы, что нарушит модель памяти. Но мы думаем, что это может произойти для любых двух магазинов с одной и той же строкой, даже первого и последнего байта.
(Это может означать, что каждая запись SB имеет 64 байта для данных, если только объединение не отличается от обычных записей SB. Но Skylake-AVX512 почти наверняка имеет 64-байтовые записи SB, потому что одно хранилище может быть таким широким. Сообщалось, что SKL и SKX в основном имеют одно и то же ядро, просто не хватает 2-го 512-битного блока FMA и, вероятно, верхнего 256-битного файла физических регистров. Таким образом, записи буфера хранения в SKL почти наверняка имеют место для 64 байтов данных, даже если более ранние процессоры этого не делают. Но на самом деле мы думаем, что у многих более ранних процессоров есть место для объединения соседних хранилищ в одну строку.)
Терминология: я использовал "объединение", чтобы говорить о слиянии в буфере хранилища, а не "объединение записи", чтобы говорить о хранилищах NT, которые объединяются в LFB, прежде чем (мы надеемся) выполнить полную запись без RFO. Или сохраняет в области памяти WC, которые делают то же самое.
Это различие / соглашение - просто кое-что, что я придумал. Согласно обсуждению в комментариях, это может не соответствовать стандартной терминологии компьютерной архитектуры.
Руководства Intel (особенно руководство по оптимизации) написаны разными авторами на протяжении многих лет и также не соответствуют их терминологии. Возьмите большую часть руководства по оптимизации с небольшим количеством соли, особенно если речь идет о Pentium4. Новые разделы о Sandybridge и Haswell являются надежными, но у более старых частей могут быть устаревшие рекомендации, которые относятся только к P4 (например, inc против add 1), или объяснения некоторых правил оптимизации микроархитектуры могут вводить в заблуждение / ошибаться. Особенно раздел 3.6.10 Write Combining. Первый пул об использовании LFB для объединения хранилищ в ожидании поступления строк для хранилищ с отсутствием кэша в WB-память просто не выглядит правдоподобным из-за правил упорядочения памяти. Смотрите обсуждение между мной и BeeOnRope, связанное выше, и в комментариях здесь.
Сноска 1:
Кэш, объединяющий записи для буферизации обратной записи (или сквозной записи) из внутренних кэшей, будет иметь другое имя. Например, семейство Bulldozer использует 16 тыс. кешей L1d сквозной записи с небольшим буфером обратной записи 4 тыс. (См. Почему кэш-память L1 и L2 тратит пространство на сохранение одних и тех же данных? За подробностями и ссылками на еще более подробную информацию. См. Оценку размера кэша в вашей системе? Для микробенчмарка перезаписи в массиве, который замедляется до 4 КБ в семействе Bulldozer. ЦПУ.)
Сноска 2. Некоторые процессоры POWER позволяют другим потокам SMT отслеживать удаленные хранилища в буфере хранилища: это может привести к тому, что разные потоки не согласятся относительно глобального порядка хранилищ из других потоков. Будут ли две атомарные записи в разные места в разных потоках всегда рассматриваться в одном и том же порядке другими потоками?
Сноска 3: процессоры, отличные от x86, со слабыми моделями памяти могут фиксировать удаленные хранилища в любом порядке, что позволяет более агрессивно объединять несколько хранилищ в одну строку, а хранилище с ошибками кэша не блокирует фиксацию других хранилищ.