Глобально Невидимые инструкции по загрузке - PullRequest
0 голосов
/ 30 мая 2018

Могут ли некоторые инструкции по загрузке не отображаться глобально из-за пересылки данных из магазина?Иными словами, если инструкция загрузки получает свое значение из буфера хранилища, она никогда не должна читать из кэша.
Поскольку обычно утверждается, что загрузка видна глобально, когда она читает из кэша L1D, те, которые не читают из L1D, должны сделать ее глобально невидимой.

Ответы [ 3 ]

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

Я не уверен, что глобальная видимость является интересной концепцией для операций загрузки (уточнение запрошено ), но если вы хотите использовать ее для урегулирования какого-либо семантического аргумента, товам придется зависеть от определений.Если, например, ваше определение глобальная видимость для нагрузок является моментом, когда оно загружает значение из кэша L1 и не допускает возможности пересылки из хранилища, тогда ответ либо «никогдастановится видимым "или" ваше определение неверно ".

На практике, однако, можно подумать, что нагрузки получают их значение из какого-то конкретного хранилища в системе.Таким образом, мы можем говорить о глобальной видимости для магазинов (и, возможно, частичного или общего заказа в этих магазинах), а затем обсудить, какие нагрузки могут получить свое значение из каких магазинов.Таким образом, ряд значений, полученных различными нагрузками, помещает их в тип глобального времени (хотя, возможно, только частично упорядоченные, если магазины упорядочены только частично).

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

В случае, если связанный хранилище в конечном итоге становится глобально видимым, у вас появляется интересный эффект типа перемещения во времени:нагрузка на локальный процессор потенциально видела хранилище намного раньше, чем другие процессоры, и, в частности, возможно, она видит его не в порядке относительно других хранилищ в системе.Этот эффект является одной из причин, по которой с системами с пересылкой хранилища обычно связано переупорядочение - например, в модели с сильной памятью x86 допустимые переупорядочения - это те, которые вызваны буферизацией хранилища и пересылкой хранилища.

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

Концепция глобальной видимости для нагрузок сложна, поскольку нагрузка не изменяет общее состояние памяти, и другие потоки не могут напрямую наблюдать его.

Но однаждыпыль оседает после неупорядоченного / умозрительного выполнения, мы можем сказать, какое значение получила нагрузка, если поток где-то ее хранит, или ветвится на ее основе.Это наблюдаемое поведение потока - вот что важно.(Или мы можем наблюдать это с помощью отладчика и / или просто рассуждать о том, какие значения могла бы видеть нагрузка, если эксперимент труден.)


По крайней мере на сильно упорядоченных процессорах, таких как x86, все процессоры могут договориться о том, что общий порядок магазинов станет глобально видимым , обновив состояние единого связного + согласованного кэша + памяти.На x86, если Переупорядочение StoreStore не разрешено, этот TSO (Total Store Order) согласуется с программным порядком каждого потока.(Т.е. общий порядок - это некоторое чередование программного порядка из каждого потока).SPARC TSO также строго упорядочен.

(Для хранилищ с обходом кэша глобальная видимость - это когда они сбрасываются из некогерентных буферов объединения записи в DRAM.)

На слабомВ упорядоченном ISA потоки A и B могут не совпадать по порядку хранилищ X и Y, выполняемых потоками C и D, даже если потоки чтения используют acqu-load, чтобы убедиться, что их собственные нагрузки не переупорядочены.т. е. не может быть глобального порядка хранилищ вообще, не говоря уже о том, чтобы он не совпадал с порядком программ.

IBM POWER ISA настолько слаб, как и CМодель памяти ++ 11 ( Будут ли две атомарные записи в разные места в разных потоках всегда рассматриваться в одном и том же порядке другими потоками? ).Это может вступить в противоречие с моделью хранилищ, которая становится видимой глобально, когда они фиксируются из буфера хранилища в кэш L1d.Но @BeeOnRope говорит в комментариях , что кэш действительно согласован и позволяет восстанавливать последовательную согласованность с барьерами.Эти эффекты многократного порядка происходят только из-за того, что SMT (несколько логических ЦП на одном физическом ЦП) вызывает необычное локальное переупорядочение.

(Один из возможных механизмов - позволить другим логическим потокам отслеживать не спекулятивные хранилища из хранилища.буферизировать даже до того, как они перейдут на L1d, сохраняя приватность только для еще не списанных хранилищ для логического потока. Это может немного уменьшить задержку между потоками. x86 не может этого сделать, потому что это сломало бы сильную модель памяти; статические разделы HT от Intelбуфер хранилища, когда два ядра активны на ядре. Но, как отмечает @BeeOnRope, абстрактная модель разрешенных переупорядочений, вероятно, является лучшим подходом для рассуждений о корректности. Просто потому, что вы не можете думать о механизме HWвызывать переупорядочение не означает, что это не может произойти. )

Слабо упорядоченные ISA, которые не так слабы, как POWER, по-прежнему переупорядочивают в буфере локального хранилища каждого ядра, если существуют барьерыили релиз-магазины не используются, хотя.На многих процессорах существует глобальный порядок для всех магазинов, но это не чередование порядка программ.ЦП OoO должны отслеживать порядок памяти, поэтому одному потоку не нужны барьеры, чтобы видеть свои собственные хранилища по порядку, но разрешение хранилищ зафиксировать хранилища из буфера хранилища в L1d вне порядка программы, безусловно, может улучшить пропускную способность (особенно если имеется несколько хранилищв ожидании той же строки, но программный порядок вытеснит строку из ассоциативно-множественного кэша между каждым хранилищем (например, неприятный шаблон доступа к гистограмме.)


Давайте проведем мысленный эксперимент о том, откуда поступают данные загрузкис

Вышесказанное относится только к видимости магазина, а не к нагрузкам. Можем ли мы объяснить значение, видимое каждой загрузкой как считываемое из глобальной памяти / кэша в какой-то момент (без учета каких-либо правил упорядочения нагрузки)?

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

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

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

(Этот глобальный общий порядок загрузки загрузки не является попыткой создать альтернативный порядок в памятимодель; у нее нет никакого способа описать действительные правила упорядочения загрузки x86.)


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

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

См. Мой ответ на Может ли x86 переупорядочить узкое хранилище с более широкой загрузкой, которая полностью его содержит? , и ответ Алекса для экспериментального доказательства того, что такое переупорядочение может произойти, что делает предложенную схему блокировки в этом вопросенедействительным. Магазин, а затем перезагрузка с того же адреса не является барьером памяти StoreLoad .

Некоторые люди (например, Линус Торвальдс) описывают это, говоря, что буфер хранилища некогерентное .(Линус отвечал кому-то еще, кто независимо придумал ту же самую недопустимую идею блокировки.)

Еще один вопрос-ответ, касающийся буфера хранения и когерентности: Как эффективно установить биты битового вектора параллельно? .Вы можете сделать неатомарное ИЛИ для установки битов, а затем вернуться и проверить наличие пропущенных обновлений из-за конфликтов с другими потоками.Но вам нужен барьер StoreLoad (например, x86 lock or), чтобы убедиться, что вы не просто видите свои собственные магазины при перезагрузке.


Загрузка становится видимой глобально, когда она читает свои данные.Обычно из L1d, но буфер хранения, MMIO или не кэшируемая память являются другими возможными источниками.

Это определение согласуется с руководствами x86, в которых говорится, что нагрузки не переупорядочиваются с другими нагрузками.то есть они загружаются (в программном порядке) из представления памяти локального ядра.

Сама загрузка может стать видимой глобально независимо от того, может ли какой-либо другой поток загрузить это значение изэтот адрес.

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

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

Пересылка из хранилища данных изменяет задержку загрузки, а не ее видимость.Если его не покраснеть из-за какого-то неправильного предположения, магазин в конечном итоге станет глобально видимым в любом случае.Без пересылки загрузки хранилища нагрузка должна ждать, пока все конфликтующие хранилища не будут удаленыТогда загрузка может получить данные в обычном режиме.

(Точное определение конфликтующего хранилища зависит от модели упорядочения памяти ISA. В x86 предполагается тип памяти WB, который допускает пересылку загрузки хранилища, любое хранилище, ранее находящееся в программном порядке и чьерасположение целевой физической памяти перекрывает то, что загружено, является конфликтующим хранилищем).

Хотя при наличии какого-либо одновременного конфликтующего хранилища от другого агента в системе это может фактически изменить загруженное значение, поскольку внешнее хранилище может вступить в силупосле локального магазина, но до локальной загрузки.Как правило, буфер хранения не находится в области когерентности, и поэтому пересылка загрузки хранилища может снизить вероятность того, что что-то подобное произойдет.Это зависит от ограничений реализации перенаправления загрузки хранилища;обычно нет никаких гарантий, что пересылка произойдет для какой-либо конкретной операции загрузки и сохранения.

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

В общем, рассмотримсистема с общей памятью с двумя агентами.Пусть S1 (A, B) будет набором возможных порядков глобальной памяти для последовательностей A и B с пересылкой с сохранением памяти, и пусть S2 (A, B) будет набором возможных порядков глобальной памяти для последовательностей A и B без сохраненияпересылкаИ S1 (A, B), и S2 (A, B) являются подмножествами набора всех допустимых порядков глобальной памяти S3 (A, B).Пересылка из хранилища может сделать S1 (A, B) не подмножеством S2 (A, B).Это означает, что если S2 (A, B) = S3 (A, B), то пересылка загрузки хранилища будет недопустимой оптимизацией.

Пересылка загрузки хранилища может изменить вероятность возникновения каждого глобального порядка памятипотому что это уменьшает задержку нагрузки.

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