|
Политики доступа и записи
Существует два широкораспространённых способа доступа к кэш-памяти со
стороны функциональных устройств процессора, сквозной и побочный, иначе
известные как Look-Through и Look-Aside. При обращении к
кэш-памяти с политикой доступа Look-Through контроллеру необходимо
сначала получить от неё ответ, а в случае отрицательного — перенаправить
запрос к контроллеру кэш-памяти более низкого уровня. При опросе кэш-памяти с
политикой доступа Look-Aside копия запроса сразу же направляется к
контроллеру кэш-памяти более низкого уровня. Обе политики имеют свои
преимущества и недостатки. Рассмотрим широкораспространённую ситуацию, в которой
запрашиваемые данные отсутствуют в D-cache (допустим, со временем доступа в 2
такта), но имеются в S-cache (допустим, со временем доступа в 4 такта). Оба кэша
являются интегрированными и управляются C-box процессора. При использовании
D-cache с политикой Look-Through C-box обязан опросить S-cache после
D-cache, поэтому только по истечении 6 тактов он будет знать, где находятся
нужные данные. Если бы D-cache придерживался политики Look-Aside, то
C-box был бы в курсе местонахождения этих данных уже после 4 тактов.
Дополнительно потребуется некоторое время на собственно доставку данных из
S-cache и помещение их в D-cache и файл регистров, но этого не избежать при
любом раскладе. В то же время и в нашем случае, политика Look-Aside
серьёзно увеличивает нагрузку на логику S-cache, производящую выборку из его
тэгов, что должно быть учтено при проектировании. В целом, на выбор той или иной
политики оказывает влияние потенциальная эффективность некоторой кэш-памяти
(potential hit rate), которая зависит, главным образом, от размера кэш-памяти и
выбранной политики ассоциативности. При относительно низкой потенциальной
эффективности более целесообразно следовать политике побочного доступа, а при
относительно высокой — сквозного.
Существует две широкораспространённые политики записи в кэш-память, сквозная
(Write-Through) и обратная (Write-Back). При записи в кэш-память
первая политика настаивает на двух одинаковых операциях сохранения: одна в
данную кэш-память и ещё одна в низлежащую кэш-память или оперативную память. В
отличие от этого, вторая политика обходится только одной операцией сохранения
— в данную кэш-память. Политику Write-Through проще применить, так
как она требует лишь наличия бита действительности для нормального
функционирования. Однако, сквозная запись является источником значительной
нагрузки по записи, которая во многих случаях нежелательна. Политика
Write-Back требует наличия бита изменённости в дополнение к биту
действительности, а также некоторой дополнительной логики для обеспечения
согласованности с оперативной памятью. Теоретически, ничто не препятствует
кэш-памяти с обратной записью работать в режиме сквозной, но не наоборот. Между
прочим, с политикой Write-Back связаны и другие интересные моменты. Если
при кэшировании новой строки возникает ситуация, что её место занято какой-то
грязной строкой, которую следует каким-то образом вытеснить, что именно делать?
Первый способ заключается в поддержании этой кэш-памяти как части низлежащей
кэш-памяти, которая обязана быть большего размера и обладать большим количеством
ассоциативностей. Если представить D-cache вместо меньшей кэш-памяти и S-cache
вместо большей, то S-cache будет всегда хранить полную копию D-cache. Таким
образом, любая строка в D-cache может быть легко перезаписана, а S-cache получит
копию новой строки, разумеется, если не имеет её к тому моменту. У этого подхода
есть один серьёзный недостаток: эффективный размер S-cache становится меньше
реального на величину D-cache. Фактически, это решение является своеобразным
гибридом политик Write-Back и Write-Through, которое вводит
понятие включающей (inclusive) кэш-памяти. Кстати, все x86 процессоры от Intel,
начиная с Pentium Pro, следуют этой модели. Другой путь заключается в том, что
в дизайн вводится небольшой межкэшевый буфер, также известный как
copy-back/victim buffer, размером обычно в 8 или 16 строк кэш-памяти. Как только
грязная строка вытесняется из D-cache, она попадает в этот буфер, где дожидается
готовности S-cache к её принятию. Следовательно, S-cache не должен хранить копию
D-cache, что и является настоящим Write-Back решением, отсюда и понятие
исключающей (exclusive) кэш-памяти. Все x86 процессоры AMD, начиная с Athlon,
следуют этой модели. С другой стороны, ничто не препятствует некоторой разработке
сочетать включающие и исключающие связи. Например, D-cache может иметь свою
копию в S-cache, но S-cache может быть полностью отвязан от T-cache. Осталось
лишь заметить, что включащие кэши легче поддерживать в многопроцессорных средах,
поскольку каждый раз требуется лишь одна проверка согласованности вместо двух.
Также стоит упомянуть о политике резервирования записи (write allocation).
Время от времени возникает ситуация, когда необходимо произвести запись в
некэшированную строку оперативной памяти. Это может быть как отдельный байт, так
и одинарное, двойное или даже учетверённое слово. Обычно в подобных случаях
C-box генерирует одиночный цикл записи в оперативную память, минуя всю иерархию
кэш-памяти. Однако, эта информация ведь может понадобиться в обозримом будущем.
В этом и заключается смысл политики резервирования записи: C-box запрашивает из
оперативной памяти чистую строку, обновляет её и записывает в некоторую
кэш-память. У этого подхода нет чётко выраженных преимуществ или недостатков. Он
может дать небольшое преимущество по производительности на некоторых задачах, но
может послужить причиной незначительного падения производительности на других
задачах из-за засорения кэш-памяти.
Для полноты картины, различают локальные и удалённые кэши. Если локальные
находится либо в ядре процессора, либо в непосредственной близости от него, то
есть в пределах процессорного конструктива, то удалённые размещают на
материнских платах. Локальная кэш-память управляется C-box процессора и обычно
использует выделенные шинные интерфейсы, а удалённая кэш-память —
системной логикой, а интерфейс к ней типично мультиплексируется с системной
шиной. Локальные кэши более быстры, но удалённые удобнее поддерживать в
многопроцессорных конфигурациях.
|