Что означает "пересылка из буфера хранилища" в руководстве разработчика Intel?

В Руководстве разработчика программного обеспечения для архитектуры Intel 64 и IA-32 говорится следующее о переупорядочении действий одним процессором (Раздел 8.2.2, "Упорядочение памяти в P6 и более поздних семействах процессоров"):

Чтения могут быть переупорядочены со старыми записями в разных местах, но не со старыми записями в том же месте.

Затем ниже при обсуждении моментов, где это смягчается по сравнению с более ранними процессорами, говорится:

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

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

3 ответа

Решение

Называть немного неловко. "Пересылка" происходит внутри ядра / логического процессора следующим образом. Если вы сначала сделаете STORE, он перейдет в буфер хранилища для асинхронной загрузки в память. Если вы выполните последующую ЗАГРУЗКУ в то же место в ОДНОМ ЖЕ ПРОЦЕССЕРЕ до того, как значение будет сброшено в кэш / память, значение из буфера хранилища будет "перенаправлено", и вы получите только что сохраненное значение. Чтение "передает" запись в том смысле, что оно происходит до фактической записи из буфера хранилища в память (что еще не произошло).

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

Несмотря на то, что здесь говорится в некоторых других ответах, нет (по крайней мере, насколько гарантируют упорядочение) НИКАКОЙ пересылки / отслеживания буфера хранилища между процессорами / ядрами, как в примере 8.2.3.5 "Внутрипроцессорная пересылка разрешена" в ручные шоу.

Я предполагаю, что зависание является понятием "буфера магазина". Отправной точкой является большое несоответствие между скоростью ядра процессора и скоростью памяти. Современное ядро ​​может легко выполнить дюжину инструкций за наносекунду. Но для получения значения, хранящегося в памяти, ОЗУ может потребоваться 150 наносекунд. Это огромное несоответствие, современные процессоры заполнены до краев хитростями, чтобы обойти эту проблему.

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

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

Проблема начинается, когда ваша программа использует более одного потока, и они получают доступ к одним и тем же ячейкам памяти. Эти потоки будут работать на разных ядрах. Много проблем с этим, заказ становится очень важным. Очевидно, что раннее чтение, выполняемое средством предварительной выборки, заставляет его читать устаревшие значения. А поздние записи, выполняемые буфером хранилища, еще хуже. Решение этого требует синхронизации между потоками. Что очень дорого, процессор легко останавливается на десятки наносекунд, ожидая, пока подсистема памяти не догонит его. Вместо потоков, делающих вашу программу быстрее, они на самом деле могут сделать ее медленнее.

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

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

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

8.2.3.5 "Внутрипроцессорная пересылка разрешена" объясняет пример пересылки в буфер хранилища:

Первоначально х = у = 0

    Processor 0             Processor 1
   ==============          =============
    mov [x], 1              mov [y], 1
    mov r1, [x]             mov r3, [y]
    mov r2, [y]             mov r4, [x]

Результат r2 == 0 а также r4 == 0 позволено.

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

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

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