Барьер памяти действует как маркер и как инструкция? - PullRequest
0 голосов
/ 14 мая 2018

Я читал разные вещи о том, как работает барьер памяти.

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

Пока пользователь Комментарий Питера Кордеса в этот вопрос говорит о том, как ЦП переупорядочивает инструкции:

Он читает быстрее, чем может выполнить, поэтому он может видеть окно предстоящих инструкций.Для получения дополнительной информации см. Некоторые ссылки в вики-теге x86, например, микроарх pdf Агнера Фога, а также статью Дэвида Кантера о разработке Intel Haswell.Конечно, если бы вы просто погуглили «не по порядку», вы бы нашли статью в Википедии, которую вы должны прочитать.

Так что я думаю, исходя из приведенного выше комментария, что еслиМежду инструкциями существует барьер памяти, CPU увидит этот барьер памяти, что заставит CPU не переупорядочивать инструкции, поэтому это означает, что барьер памяти является «маркером», который процессор может видеть и не выполнять.


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

Для маркерной части CPU видит барьер памяти между инструкциями,что приводит к тому, что ЦП не переупорядочивает инструкции.

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

Я прав?

1 Ответ

0 голосов
/ 14 мая 2018

Нет, mfence не сериализуется в потоке инструкций, а lfence (что) не очищает буфер хранилища.

(На практике на Skylake, mfence блокирует неупорядоченное выполнение более поздних инструкций ALU, а не только загрузку. ( Доказательство: подробности эксперимента внизу этого ответа ). Таким образом, оно реализовано как барьер выполнения, даже если включенобумага, это не обязательно должен быть один. Но lock xchg нет, и это также полный барьер.)

Я бы предложил прочитать Барьеры памяти Джеффа Прешинга, как операции управления источником статьи, чтобы лучше понять, что нужно делать с барьерами памяти, и что они не должны делать.В общем случае они не должны блокировать выполнение не по порядку.


Барьер памяти ограничивает порядок, в котором операции с памятью могут стать глобально видимыми, не (обязательно) порядок выполнения инструкций. Снова прочитайте обновленный ответ @ BeeOnRope на ваш предыдущий вопрос: Есть ли инструкции по переупорядочению процессора x86? чтобы узнать больше о том, как переупорядочение памяти может происходить без OoOexec, и как OoO exec может происходить без переупорядочения памяти.

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

x86 уже требует много памяти- отслеживание порядка для обычных нагрузок / хранилищ для высокой производительности при сохранении строго упорядоченной модели памяти, где только переупорядочение StoreLoad разрешено быть видимым для наблюдателей вне ядра (то есть хранилища могут буферизироваться до последующих загрузок),(Руководство по оптимизации Intel использует термин Memory Order Buffer, или MOB, вместо буфера хранения, потому что он также должен отслеживать порядок загрузки. Он должен очистить машину упорядочивания памяти, если окажется, что спекулятивная нагрузка тоже приняла данныена ранних этапах.) Современные процессоры x86 сохраняют иллюзию уважения к модели памяти, в то время как фактически выполняют загрузки и агрессивно хранят неупорядоченно.

mfence может выполнить свою работу, просто записав маркер в память.буфер ордеров, не являющийся барьером для выхода из строя исполнения более поздних инструкций ALU .Этот маркер должен по крайней мере препятствовать выполнению последующих загрузок, пока маркер mfence не достигнет конца буфера хранения.(Как и упорядочение хранилищ NT и операций со слабо упорядоченной памятью WC).

(Но опять-таки, более простое поведение является допустимым вариантом реализации, например, не позволяя хранилищам после mfence записывать данные всохраняйте буфер до тех пор, пока все более ранние загрузки не прекратятся, а более ранние хранилища не перейдут в кэш L1d, т. е. полностью истощат буфер MOB / store. Я не знаю точно, что делают текущие процессоры Intel или AMD.)


В частности, на Skylake в моем тестировании показано, что mfence составляет 4 моп для внешнего интерфейса (слитый домен) и 2 мопа, которые фактически выполняются на портах исполнения (один для порта 2/3 (load / store-address)) и один для port4 (store-data)).Предположительно это особый тип UOP, который записывает маркер в буфер порядка памяти.2 мопа, которые не нуждаются в исполнительном блоке, могут быть похожи на lfence.Я не уверен, блокируют ли они интерфейсную часть даже от более поздней загрузки, но, надеюсь, не потому, что это остановит выполнение последующих независимых операций ALU.


lfence является интересным случаем: помимо барьера LoadLoad + LoadStore (даже для слабо заказанных нагрузок; обычные нагрузки / хранилища уже заказаны), lfence также слабое исполнение барьер (обратите внимание, что mfence нет, просто lfence). Невозможно выполнить, пока все более ранние инструкции не будут «выполнены локально». Предположительно, это означает, что «вышел в отставку» из ядра, вышедшего из строя.

Но магазин не может зафиксировать кэш L1d до тех пор, пока после он все равно не удалится (т.е. после того, как он, как известно, не будет спекулятивным), поэтому ждет, пока магазины выйдут из ROB (ReOrder Buffer для мопов) ) это не то же самое, что ожидание очистки буфера хранилища. См. Почему SFENCE + LFENCE (или нет?) Эквивалентны MFENCE? .

Так что да, конвейер ЦП должен «заметить» lfence до того, как он запустится, предположительно на этапе выдачи / переименования . Насколько я понимаю, lfence не может выдать, пока ROB не опустеет. (В процессорах Intel lfence - это 2 мопа для внешнего интерфейса, но ни один из них не требует исполнительных блоков, согласно тестированию Agner Fog. http://agner.org/optimize/.)

lfence еще дешевле для семейства AMD Bulldozer: 1 моп с пропускной способностью 4 на тактовую частоту. IIRC, он частично не сериализован на этих процессорах, поэтому вы можете использовать lfence; rdtsc только для того, чтобы rdtsc не смог сэмплировать часы раньше на процессорах Intel.


Для полностью сериализованных инструкций, таких как cpuid или iret, он также будет ожидать, пока буфер хранилища не будет исчерпан. ( Они являются полными барьерами памяти, такими же сильными, как mfence). Или что-то типа того; они являются множественными мопами, так что, возможно, только 1096 * последний один выполняет сериализацию, я не уверен, с какой стороны барьера происходит фактическая работа cpuid (или если она не может перекрываться более ранние или более поздние инструкции). В любом случае, сам конвейер должен замечать сериализованные инструкции, но полный эффект барьера памяти может быть от мопов, которые делают то, что делает mfence.


Бонусное чтение:

В семействе AMD Bulldozer стоимость sfence такая же высокая, как и mfence, и может быть таким же сильным барьером. (Документы x86 устанавливают минимум для того, насколько силен каждый тип барьера; они не мешают им быть сильнее, потому что это не проблема правильности). Ryzen отличается: sfence имеет один на пропускную способность 20c, в то время как mfence равен 1 на 70c.

sfence очень дешевый для Intel (моп для port2 / port3 и моп для port4), и он просто заказывает NT-магазины в отношении. обычные хранилища, без очистки буфера хранилища или выполнения сериализации. Может выполняться один раз в 6 циклов.

sfence не истощает буфер хранилища перед выходом на пенсию. Он не становится глобально видимым сам по себе, пока все предыдущие хранилища не станут глобально видимыми первыми, но это не связано с выполнением конвейер по буферу хранилища . Буфер хранилища всегда пытается опустошить себя (т. Е. Зафиксировать хранилища в L1d), поэтому sfence не нужно делать ничего особенного, за исключением размещения особого вида метки в MOB, которая мешает хранилищам NT переупорядочивать его, в отличие от отметки, которые ставят обычные магазины, которые только заказывают по отношению. обычные магазины и более поздние грузы.


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

См. этот ответ, который я написал , который является более подробной версией моего комментария. В нем рассматриваются некоторые основы того, как современный процессор x86 находит и использует параллелизм на уровне команд, рассматривая еще не выполненные инструкции.

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

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