Обеспечивают ли заблокированные инструкции барьер между слабоупорядоченными доступами?

В x86 инструкции с префиксом lock, такие как lock cmpxchg, обеспечивают семантику барьера в дополнение к своей атомарной операции: для нормального доступа к памяти в областях памяти с обратной записью операции чтения и записи не переупорядочиваются в инструкциях с префиксом lock, согласно разделу 8.2.2. Тома 3 Intel SDM:

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

Этот раздел относится только к типам памяти с обратной записью. В том же списке вы найдете исключение, в котором отмечается, что магазины со слабой упорядоченностью не упорядочиваются:

  • Чтения не переупорядочиваются с другими чтениями.
  • Записи не переупорядочиваются со старыми чтениями.
  • Записи в память не переупорядочиваются с другими записями, за следующими исключениями: -
    # P4 # # P5 #

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

В различных других разделах руководства упоминается, что инструкции mfence и / или sfence могут использоваться для упорядочивания памяти, когда используются слабо упорядоченные (невременные) инструкции. В этих разделах обычно не упоминается инструкция с префиксом lock в качестве альтернативы.

Все это оставляет меня неуверенным: обеспечивают ли инструкции с префиксом lock тот же полный барьер, который обеспечивает mfence между слабо упорядоченными (невременными) инструкциями в памяти WB? Тот же вопрос применим снова, но к любому типу доступа к памяти WC.


person BeeOnRope    schedule 10.05.2018    source источник


Ответы (2)


На всех 64-битных процессорах AMD MFENCE является инструкцией полной сериализации, а инструкции с префиксом Lock - нет. Однако оба сериализуют все обращения к памяти в соответствии с руководством AMD V2 7.4.2:

Все предыдущие загружаются и сохраняются в памяти или пространстве ввода-вывода до того, как будет выдан доступ к памяти для ввода-вывода, блокировки или инструкции по сериализации.

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

Нет никаких исключений или ошибок, связанных со свойствами сериализации этих инструкций.

Из руководства Intel и документов ясно, что в обоих случаях все хранилища сериализуются без исключений или связанных с ними ошибок. MFENCE также сериализует все загрузки с одной ошибкой, задокументированной для большинства процессоров на базе микроархитектур Skylake, Kaby Lake и Coffee Lake, в которой говорится, что MOVNTDQA из памяти WC может передавать более ранние MFENCE инструкции. Кроме того, многие процессоры, основанные на микроархитектурах Nehalem, Sandy Bridge, Ivy Bridge, Haswell, Broadwell, Skylake, Kaby Lake, Coffee Lake и Silvermont, имеют ошибку, в которой говорится, что MOVNTDQA из памяти WC может передавать ранее заблокированные инструкции. Процессоры на базе микроархитектур Core, Westmere, Sunny Cove и Goldmont не имеют этой ошибки.

В цитате из ответа Necrolis говорится, что префикс блокировки не может сериализовать операции загрузки, которые ссылаются на слабо упорядоченные типы памяти на процессорах Pentium 4. Насколько я понимаю, это похоже на ошибку в процессорах Pentium 4 и не распространяется ни на какие другие процессоры. Хотя стоит отметить, что это не задокументировано в документах обновления спецификаций процессоров Pentium 4.


эксперименты @ PeterCordes что в Skylake инструкции блокировки, похоже, не блокируют выполнение инструкций ALU не по порядку, в то время как mfence сериализует инструкции ALU (потенциально идентично lfence + очистка буфера хранилища, как заблокированная инструкция). Однако я думаю, что это деталь реализации.

person Hadi Brais    schedule 12.05.2018
comment
Интересно, почему для выполнения mfence требуется гораздо больше времени, чем для заблокированных инструкций, если он менее мощный? - person BeeOnRope; 12.05.2018
comment
Часть о том, что предварительная выборка не упорядочена по различным инструкциям, для меня либо странна, либо очевидна. Инструкции предварительной выборки не имеют никакого архитектурного эффекта (видимый вывод) и по сути являются подсказками для перемещения строк в кеш - они должны использоваться последующими инструкциями загрузки, которые должны выполняться по правилам упорядочивания памяти. Таким образом, я не вижу ни одного сценария (за пределами производительности), где предварительная выборка не упорядочена по сравнению с предложением X, что приведет к тому, что предварительная выборка будет упорядочена по сравнению с X. - person BeeOnRope; 12.05.2018
comment
@BeeOnRope Два простых примера, где упорядочивание программной предварительной выборки имеет значение, которые я могу сейчас придумать. 1 - при изменении режима адресации памяти (подкачка, защита, структуры подкачки) это меняет способ интерпретации адреса предварительной выборки. 2- предварительная выборка может устанавливать бит доступа в одном или нескольких дескрипторах сегмента и структурах поискового вызова, что является заметным архитектурным изменением. Кроме того, существует сложное взаимодействие между программной предварительной выборкой и другим поведением процессора. Порядок инструкций предварительной выборки, безусловно, имеет значение и специально разработан таким образом. - person Hadi Brais; 12.05.2018
comment
@BeeOnRope По поводу вашего первого комментария. Не знаю почему. Вы должны подробно описать, как вы измеряете производительность, чего я не делал. Я предлагаю опубликовать его как новый вопрос, если хотите. - person Hadi Brais; 12.05.2018
comment
На данный момент я просто смотрю на таблицы Агнера, в которых все mfence составляют ~ 33 цикла, а сложные заблокированные инструкции, такие как lock cmpxchg, в целом составляют 15-20 циклов. Я еще не проверял лично, но подозреваю, что это правильно, так как в целом не использовать mfence, просто использовать команду no-op lock op, вместо этого было общепринятым мнением о производительности в течение некоторого времени. Поэтому я сомневаюсь, что mfence значительно дешевле, чем указано. Я мог бы задать другой вопрос, но почему (неясная) инструкция X быстрее, чем (неясная) инструкция типа Y, по моему опыту, как правило, используются магниты закрытия / отрицания. - person BeeOnRope; 13.05.2018
comment
@BeeOnRope Я тебя чувствую. Теперь я думаю, что, возможно, вам не стоит беспокоиться о публикации вопроса, потому что я читал в нескольких документах, что инструкции, которые предлагают только более слабые гарантии заказа, могут быть реализованы внутри точно так же, как инструкции, которые предлагают более строгие гарантии заказа. Просто гарантии публично не документированы. Но мы никогда не сможем узнать наверняка, если Intel не сообщит нам. - person Hadi Brais; 13.05.2018
comment
На самом деле, я не считаю, что более слабая реализация как более сильная представляет собой проблему: это Intel оставляет открытой дверь для будущих оптимизаций и / или различных реализаций в своей документации ISA. В этом нет особого недостатка: люди, которые согласны с более слабыми гарантиями, используют более слабые инструкции, и даже если они в конечном итоге проявляют более сильное поведение, они, по крайней мере, связаны с гарантированно сильным поведением других инструкций. - person BeeOnRope; 13.05.2018
comment
Этот случай mfence является своего рода противоположным: возможно, mfence имеет более строгие гарантии (ваш ответ говорит, что нет, но я также вижу противоположный случай - см. здесь несколько аргументов), но если этого нет в текущей архитектуре (вы говорите, что она строго слабее), почему бы Intel не реализовать его с теми же базовыми примитивами, что и другие инструкции? Для меня это не имеет смысла. OTOH, документирование инструкций как имеющих, возможно, более слабую семантику, но не всегда (или когда-либо) реализация этого на каждой арке имеет смысл. - person BeeOnRope; 13.05.2018
comment
@BeeOnRope Что ж, на уровне ISA он сильнее по сравнению с другими инструкциями по ограничению, а не с блокировками с префиксом. На уровне реализации mfence может иметь те же свойства сериализации, что и префикс блокировки, но определенно не может обеспечивать атомарность. - person Hadi Brais; 13.05.2018
comment
@BeeOnRope Я быстро рассмотрел ваш ответ на этот вопрос, который кажется противоположным моему. Но, похоже, вы пропустили цитаты, которые я упомянул в своем ответе, которые могли привести вас в другую сторону. - person Hadi Brais; 13.05.2018
comment
Да, это наоборот, но я думаю, что на самом деле это неправильно и что более вероятно, что lock инструкции сериализуют слабо упорядоченный доступ к памяти, но просто реализуются по-другому, что делает их быстрее - по крайней мере, в тесте на обратную задержку. Кажется, что возможно mfence имеет некоторое дополнительное поведение сериализации в случае непонятных вещей, таких как cflushopt и (возможно, а может и нет) инструкции предварительной выборки. - person BeeOnRope; 17.05.2018
comment
@BeeOnRope Согласно руководству Intel V2, как MFENCE, так и заблокированные инструкции сериализуют как CLFLUSH, так и CLFLUSHOPT. Кроме того, как также упоминалось в ответе, оба не упорядочены по PREFETCHh и PREFETCHW. - person Hadi Brais; 17.05.2018
comment
Я искал в разделе упорядочивания 8.2.2 в V3, который AFAIK в основном является основным списком правил упорядочивания, и там они перечисляют ограничения на упорядочение между cflushopt и различными ограждениями, но ни одного с заблокированными инструкциями. Вы правы, что в описании CFLUSHOPT в V2 упоминается, что он упорядочен по заблокированным инструкциям. Я упомянул предварительную выборку, потому что в их mfence патенте единственный пример использования Intel - это mfence, используемый для отделения prefetch инструкции от невременного хранилища. - person BeeOnRope; 17.05.2018
comment
Может случиться так, что, несмотря на предостережение в руководстве, предварительная выборка упорядочена mfence (и, возможно, заблокированными инструкциями) на текущих архитектурах, но Intel не хочет заблокировать себя таким поведением. - person BeeOnRope; 17.05.2018
comment
@BeeOnRope Мне кажется, что нет противоречия между тем, что написано в V2 и V3. Гарантии упорядочения в V2 являются надлежащим подмножеством гарантий в V3. Также в V2 они говорят только CLFLUSH and CLFLUSHOPT cannot pass **earlier** LFENCE, но для других ограждений он работает в обоих направлениях, как указано в V2. Что с этим? В V3 правила упорядочивания одинаковы для всех ограждений, включая LFENCE, и работают в обоих направлениях, что имеет больше смысла. - person Hadi Brais; 17.05.2018
comment
В руководстве много таких нестыковок. Они даже не используют слово сериализовать (как в инструкции сериализации) последовательно. Тем не менее, я, вероятно, поверил бы V2 здесь: если они документируют в cflushopt, что заблокированные инструкции сериализуются, они, вероятно, так и сделают. Иногда легче понять руководство, если учесть, что оно было написано не в один момент времени, а скорее в несколько этапов с добавлением новой информации по мере добавления новых процессоров. Уровень детализации и формата новой информации не обязательно должен быть таким же, как у старой. - person BeeOnRope; 17.05.2018
comment
Вы можете часто видеть это в руководстве по оптимизации, где оно было написано в какой-то момент для какой-то древней архитектуры, а затем обновлено много раз для новых, но процесс обновления не является точным или исчерпывающим. Итак, у вас есть много разделов, в которых упоминаются только старые архитектуры, и они могут относиться к новым архитектурам или нет, или советы могут даже быть противоположными тому, что нужно новой архитектуре. Добавляются новые разделы, которые применяются к новым архитектурам, которые могут или не могут применяться к старым, и так далее. То же самое и с руководством по системному программированию: возможно, когда были добавлены sfence, mfence и друзья ... - person BeeOnRope; 17.05.2018
comment
... они прошли и добавили новые строки для них в правилах упорядочивания, в которых упоминались cflush и (позже) clushopt, потому что это было указано в дискуссии между документом и инженером, разговаривавшим с ними, но затем они не вернитесь и обновите строки блокировки. Точно так же одна и та же концепция часто затрагивается во многих местах (например, сериализация, порядок инструкций и порядок памяти), но иногда только некоторые места обновляются, когда документируется новое поведение, инструкция или гарантия, оставляя другие устаревшими и корм для дебатов. - person BeeOnRope; 17.05.2018
comment
@BeeOnRope Да, полностью согласен. Я бы добавил также использование разных терминов для обозначения одного и того же, неопределенных терминов, расплывчатых предложений и неполного описания функций или правил. Когда я сказал no inconsistency, я имел в виду только функциональную правильность тех конкретных частей руководства, которые мы обсуждаем. Но я думаю, что V2 более точен, обновлен и более хорошо написан, чем V3. Я не думаю, что раздел 8.2.2 обновлялся уже давно. - person Hadi Brais; 17.05.2018
comment
@BeeOnRope Может быть, было бы неплохо, если бы Intel создала репозиторий GitHub для руководств, чтобы люди могли отправлять проблемы и прочее. - person Hadi Brais; 17.05.2018
comment
Ой, я прочитал это, потому что есть несоответствие, а не несоответствие, поэтому начальная часть моего ответа не имеет смысла. Я не уверен, что вы подразумеваете под правильным подмножеством в этом случае. Вы говорите о наборе ограничений поверх неупорядоченной модели (так, например, что набор правил, разрешающий только переупорядочение загрузки магазина, будет надмножеством того, что разрешено переупорядочение load-load и store-load - поскольку у первого больше гарантий)? Или вы имеете в виду обратное, например, что набор представляет собой список возможных переупорядочений поверх номинально последовательно ... - person BeeOnRope; 17.05.2018
comment
... согласованная модель, так что в приведенном выше примере первые правила будут подмножеством? В любом случае я не считаю, что правила в 8.2.2 являются подмножеством или надмножеством V2: V2 предоставляет сильные гарантии в случае cflushopt, но гораздо более слабые гарантии в других случаях, поскольку в нем даже не обсуждается порядок в целом. (т.е. вы не найдете запрета на повторный заказ магазина-магазина, AFAIK). Это своего рода пункт 8.2.2 - перечислить все гарантии упорядочения в одном месте, а не пытаться распространять их по инструкции, где во многих случаях нет очевидного источника. - person BeeOnRope; 17.05.2018
comment
Кстати, думаю 8.2.2. обновляется довольно часто, например, это относится к clflushopt, которая является недавней инструкцией (добавлена ​​только в Skylake?). Этот раздел также претерпел множество изменений и был предметом многочисленных споров в прошлом, когда модель была слабее реальности, плохо определялась и так далее. Есть даже научные статьи, которые пытаются формализовать. Вот почему раздел такой большой, в нем столько лакмусовых бумажек и прочего. Так что я думаю, вы можете сказать, что в этом разделе определенно было вложено много усилий выше среднего. - person BeeOnRope; 17.05.2018
comment
Кроме того, описание LFENCE меня не удивляет. Насколько мне известно, lfence просто приостанавливает выполнение до тех пор, пока все старые инструкции не будут выполнены (не будут удалены?). Этого достаточно, чтобы ограничить инструкции загрузки, которые вступают в силу при выполнении (и требуется только для нагрузок, которые обходят обычные гарантии упорядочивания). Поведение по отношению к инструкциям, подобным хранению (например, clflush*), тогда будет заключаться в предотвращении передачи более поздних инструкций, подобных хранению, поскольку они даже не запускаются до тех пор, пока lfence не выполнит сериализованное выполнение инструкций, а не более ранние из-за буфера хранения. - person BeeOnRope; 17.05.2018
comment
@BeeOnRope Я имел в виду, что гарантии заказа в отношении clflush(opt) и инструкций ограждения и блокировки, упомянутые в 8.2.2, более мягкие (меньше гарантий), чем в V2. Да, это может не относиться ко всему в V2 и V3. Но я бы не назвал это несоответствием, это скорее неполнота. - person Hadi Brais; 17.05.2018
comment
@BeeOnRope Я подумал о создании вопроса о переполнении стека, чтобы в основном создать дом для всех правил упорядочивания в x86 с учетом всех инструкций, всех типов памяти и даже модулей DIMM 3D XPoint. Но я не уверен, что это хорошая идея; люди могут не приветствовать такие вопросы. - person Hadi Brais; 17.05.2018
comment
Несомненно, было бы сложно поместить канонический документ по всем порядкам в один вопрос в формате вопросов и ответов. Это было бы лучше для чего-то вроде функции SO doc (которая была удалена). Я думаю, что лучшее, на что мы можем надеяться, - это серия вопросов по ключевым моментам с хорошими / каноническими ответами и, возможно, ссылки на них в вики-странице тегов или какой-либо главный вопрос, если можно пожелать подходящий. Тем не менее, я лично не сторонник правил SO, поэтому, если кто-то хочет попытаться втиснуть это в один вопрос, я приветствую эти усилия. - person BeeOnRope; 18.05.2018
comment
Хорошая статья. Я добавил комментарий по поводу чего-то, чего не понял, и еще нескольких моментов. - person BeeOnRope; 18.05.2018

Блокировки шины (с помощью префикса кода операции LOCK) создают полное ограждение *, однако в памяти WC они не обеспечивают ограничение нагрузки, это описано в Руководстве разработчика программного обеспечения Intel 64 и IA-32, том 3A, 8.1. 2:

Для процессоров семейства P6 заблокированные операции сериализуют все невыполненные операции загрузки и сохранения (то есть дождаться их завершения). Это правило также справедливо для процессоров Pentium 4 и Intel Xeon, за одним исключением. Операции загрузки, которые ссылаются на слабо упорядоченные типы памяти (такие как тип памяти WC), не могут быть сериализованы.

* См. Пример в Руководстве разработчика программного обеспечения для архитектур Intel 64 и IA-32, том 3A, 8.2.3.9.

person Necrolis    schedule 10.05.2018
comment
Имена поколений их процессоров очень плохи в ручном режиме. Похоже, что многие из них были обновлены в эпоху P4. Что они подразумевают под процессорами Xeon? Понятно, что это не может относиться к процессорам Xeon под брендом, поскольку они существуют почти на каждой микроархитектуре и не коррелируют с таким базовым поведением. Таким образом, из приведенного выше неясно, в каком состоянии находятся новые процессоры. - person BeeOnRope; 11.05.2018
comment
@BeeOnRope Я полностью согласен, но я склонен понимать, что это означает «От P6 до настоящего времени», и когда я вижу Xeon, я склонен воспринимать это как ISA IA64 (Itanium); который имеет другую семантику памяти, чем x86. Я полагаю, что единственный действительно окончательный способ - это построить тестовую платформу (я не помню, отслеживает ли IACA семантику памяти в этом отношении). - person Necrolis; 11.05.2018
comment
Ну P6 относится к архитектуре PPro, которая предшествовала на много лет P4 (в первом случае 6 является продолжением 486, 586 (Pentium), 686 (PPro) - тогда как в случае P4 это числовое продолжение Pentium I, Pentium II, Pentium III). Конечно, микросхемы, которые следовали за P4, были производными от архитектуры P6, поэтому, возможно, совет для P6 применяется как до , так и после P4. Однако есть места, где P6 определенно относится только к старым чипам до P4, например, поскольку из контекста явно видно, что они только 32-битные. - person BeeOnRope; 12.05.2018
comment
Я не думаю, что Xeon может ссылаться на Itanium, поскольку эти руководства охватывают только архитектуру x86 и x86-64 (то, что Intel называет IA-32 и Intel-64). - person BeeOnRope; 12.05.2018