Как политика записи-недействительности работает с ассоциативными кэшами?

Я просматривал политики записи в кэш статья Нормана П. Джуппи, и я понимаю, почему функция write-invalidate (определенная на стр. 193) хорошо работает с кешами с прямым отображением, что связано с возможностью записи данных, которые проверяют тег, и, если обнаружено, что они пропущены, строка кеша является недействительным, поскольку он поврежден записью. Это можно сделать за один цикл. Но есть ли польза от использования write-invalidate для ассоциативных кешей? Какая обычная конфигурация используется для кэшей L1 в реальных процессорах? Используют ли они прямую или ассоциативную политику и политику записи-проверки / записи / записи недействительной / выборки-при-записи?


person Nebula    schedule 06.01.2021    source источник


Ответы (1)


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

Запись-недействительность имеет смысл только для простого упорядоченного конвейера с простым кешем, который пытается избежать остановки конвейера даже без буфера хранения и работает очень быстро за счет скорости совпадений. Если бы вы собирались что-то изменить, чтобы повысить частоту совпадений, отказ от записи-недействительности (обычно на обратную запись + запись-выделение + выборку-при-записи) был бы одним из первых. Запись-недействительность с ассоциативным кешем возможна с некоторыми уродливыми компромиссами, но вам не понравятся результаты.


В документе 1993 года, на который вы ссылаетесь, этот термин используется для обозначения чего-то другого, кроме современного механизма согласованности кеша, означающего < / а>. В статье:

Комбинацию write-before-hit, no-fetch-on-write и no-write-allocate мы называем write-invalidate.

Да, реальные кеши в наши дни в основном всегда ассоциативны по множеству; более сложная логика компаратора тегов стоит увеличения частоты совпадений для того же размера данных. Какой метод сопоставления кэша используется в Intel Core i7 процессор? есть кое-что общее, а не только x86. Современные примеры кэшей с прямым отображением включают кэш DRAM, когда часть постоянной памяти на платформе Intel работает в режиме памяти. Также многие процессоры серверного уровня от разных производителей поддерживают разделение на разделы L3, поэтому вы можете, например, выделить один путь для потока, который в основном будет вести себя как кэш с прямым отображением.

Политика записи для современных кэшей ЦП обычно такая: запись-распределение + выборка при записи + запрет записи до попадания; некоторые ISA предлагают такие методы, как специальные инструкции для обхода кеша для невременных хранилищ, которые не будут перечитаны в ближайшее время, чтобы избежать загрязнения кеша в таких случаях. Большинство рабочих нагрузок перезагружают свои хранилища с достаточной временной локальностью, поэтому запись-выделение - единственный разумный выбор, особенно когда кеши больше и / или более ассоциативны, поэтому они с большей вероятностью смогут зависнуть в строке до следующего чтения. или напишите.

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


Но есть ли польза от использования write-invalidate для ассоциативных кешей?

Похоже, что это не так.

Единственное преимущество, которое он имеет, заключается в том, что он не останавливает простой конвейер, в котором отсутствует буфер хранения (буфер записи в документе). Это позволяет писать параллельно с проверкой тегов, поэтому вы узнаете после изменения строки, нажали вы или нет. (Современные процессоры действительно используют буфер хранилища для отделить фиксацию хранилища до L1d от выполнения хранилища и скрыть задержку отсутствия сохранения. Даже у ЦП в порядке обычно есть буфер хранилища, чтобы обеспечить параллелизм RFO на уровне памяти (чтение для владения) . (например, ARM Cortex-A53 в телефонах).

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

Слепое написание случайным образом может привести к ситуации, когда попадание произойдет не так, как вы предполагали. Прогнозирование пути - это вещь (и может работать лучше, чем случайное), но обратная сторона неправильного предсказания для такой записи будет излишне недействительной строкой, а не просто небольшой дополнительной задержкой. Прогнозирование пути в современном кэше. Я не знаю, какого рода успешное предсказание пути обычно достигается. Думаю, не очень хорошо, в лучшем случае от 80 до 90%. Наверное, лучше потратить транзисторы на предсказание пути, потратить на что-то другое, на что-то менее отстойное, чем запись-недействительность! Буфер хранилища с переадресацией хранилища, вероятно, стоит дороже, но он намного лучше.

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

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

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

Вы не хотите победить это, снося линии, которым не нужно было умирать.

Кроме того, write-invalidate подразумевает сквозную запись даже для попаданий записи, потому что это может привести к потере данных, если строка когда-либо станет грязной. Но обратная запись также очень хороша в современных кэшах L1d, чтобы изолировать большие / более медленные кеши от пропускной способности записи. (Особенно, если нет частного L2 для каждого ядра, чтобы отдельно уменьшить общий трафик к общим кэшам.) Однако в семействе AMD Bulldozer был L1d со сквозной записью с небольшим буфером записи 4k между ним и L2 с обратной записью. Обычно это считалось неудачным экспериментом или слабым местом конструкции, и они отказались от него в пользу стандартного L1d с обратной записью и выделением памяти для Zen. При использовании политики сквозного кеширования для страниц.

Таким образом, запись-недействительность несовместима с несколькими вещами, которые современные конструкции ЦП считают лучшими вариантами, которые вы найдете в большинстве конструкций ЦП.


запись-недействительность в системах SMP с когерентным кешем

Вы бы никогда не подумали об использовании его в одночиповом многоядерном процессоре; потратьте больше транзисторов на каждое ядро, чтобы получить больше низко висящих плодов, прежде чем вы начнете строить больше ядер. например надлежащий буфер хранилища. Используйте некоторый вариант SMT, если вам нужна высокая пропускная способность для нескольких потоков с низким IPC, которые часто останавливаются.

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

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

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

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

Случай записи в строку, которая не еще до L2, интересен: если это попадание записи L0d, вы эффективно получаете слияние магазинов бесплатно. Для этого вам понадобятся биты обратной записи на каждое слово или на побайты (также известные как грязные биты). Обычно сквозная запись отправляется вместе с записью, пока смещение внутри строки все еще доступно, но если L2 еще не готов принять его (например, из-за промаха записи), вы не можете этого сделать. Это превращает его в буфер комбинирования записи. Пометка всей строки как требующей обратной записи не работает, потому что незаписанные части по-прежнему недействительны.

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

Возможно, все еще можно выполнить эту работу: если доступ к кешу представляет собой обмен чтением + записью, который сохраняет предыдущее значение в буфере из одного слова (или независимо от максимального размера записи), у вас все еще есть все данные. Остановите все (включая обратную запись этой строки, чтобы вы не сделали неправильные данные глобально видимыми в согласованном кэше L2). Затем обменяйтесь обратно, дождитесь, пока старое состояние этой строки L0d действительно обратится к этому адресу, затем сохраните буфер tmp в L0d и обновите теги и биты обратной записи, чтобы отразить это хранилище. Таким образом, псевдонимы между ближайшими магазинами становятся более дорогостоящими и останавливают конвейер. Или, может быть, вы можете позволить инструкциям, не относящимся к памяти, продолжаться и останавливать выполнение только при следующей загрузке или сохранении. (Если у вас есть бюджет транзисторов, чтобы избежать срывов, вы, вероятно, можете просто использовать совершенно другую стратегию, например, иметь буфер хранения и нормальный L1d.)

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

person Peter Cordes    schedule 06.01.2021
comment
Политика признания недействительной записи, упомянутая в вопросе, связана не с согласованностью кеша, а скорее с политикой пропуска записи. См. Статью, на которую я указал в вопросе, чтобы получить полный контекст вопроса. - person Hadi Brais; 06.01.2021
comment
@HadiBrais: спасибо, обновлено. Это делает вопрос более понятным; Я предполагаю, что речь идет о систематике деталей для политик запрета записи и выделения. Не уверен, в чем в этом случае смысл записи до попадания, зачем портить идеально хорошую строку кэша, если вы не собираетесь ее заменять. Может быть, просто добавлено для полноты картины. Ах, позже в документе упоминается, что этому могут способствовать соображения практической реализации, такие как неблокирование (конвейерная обработка?). Я думаю, они рассматривают конвейер в порядке, возможно, без буфера хранилища + перенаправления хранилища. - person Peter Cordes; 06.01.2021
comment
... учитывая обсуждение этапа конвейера MEM и устаревание цикла сохранения на 1, чтобы убедиться, что он завершится без исключения. - person Peter Cordes; 06.01.2021
comment
Да, похоже, так. Выполнение записи одновременно с проверкой тега может сэкономить 1 цикл, поэтому конвейер упорядочения без буфера хранения (называемый в документе буфером записи) не должен потенциально останавливаться на 1 цикл. Запись-недействительность также устраняет необходимость остановки до тех пор, пока строка не будет выбрана при промахе (в статье предполагается, что на первой странице запись не завершится до тех пор, пока строка не будет выбрана в политике выборки-при-записи). Обратите внимание, что ваш ответ пытается ответить только на две последние части вопроса. - person Hadi Brais; 06.01.2021
comment
@HadiBrais: Ваш запрос меня достаточно заинтересовал, чтобы написать больше и ответить на первую часть: полезно ли это с ассоциативным набором. Так что спасибо, наверное: P - person Peter Cordes; 06.01.2021
comment
Параграф о совместимости с MESI выглядит неверным. Запись-недействительность может в основном рассматриваться как кеш со сквозной записью, вам не нужны состояния M или E, но все же вы должны отправлять недействительные, чтобы убедиться, что существует только одно глобальное состояние. - person Hadi Brais; 06.01.2021
comment
@HadiBrais: Спасибо, это осталось от моей предыдущей версии моих размышлений о том, может ли / как это работать, прежде чем я понял, что это может быть несогласованным, как я говорил позже. И я поленился в своем последнем чтении, прежде чем опубликовать эту правку. Спасибо за другие правки, интересная идея написать все способы набора. Это был бы полный мусор, если только записи не были редкими по сравнению с чтениями, и, вероятно, улучшили бы более низкую ассоциативность (даже до 1) для общей частоты совпадений для многих рабочих нагрузок, увеличивая эффективную полезную емкость. - person Peter Cordes; 06.01.2021