Подсистема кэша архитектуры К8.
реклама
В связи с большим числом вопросов и непоняток в теме https://forums.overclockers.ru/viewtopic.php?t=123341&postdays=0&postorder=asc&start=0 о различиях архитектур к8 и netburst, ставлю здесь отметку о подсистеме кэша в К8. Вся информация взята с сайта IXBT.COM, за что им огромное спасибо.
Собственно, сам текст:
Подсистема кэша. Поиск и анализ изменений
Одним из важных слагаемых для результирующей производительности процессора является производительность подсистемы кэширования. Кэш-память призвана сгладить разницу в скоростях оперативной памяти и самого процессора, поэтому она находится на «переднем крае» борьбы с постоянным недостатком данных для процессора. Как известно, кэш в K7 имел несколько узких мест, в связи с чем было бы очень интересно узнать, что же, кроме объема, изменилось в организации кэша в К8 по сравнению с Athlon XP.
В общем случае, производительность кэша характеризуется несколькими параметрами: задержками (Latency), и темпом (throughput), а также некоторыми другими понятиями вроде типа ассоциативности (впрочем, о нем и других параметрах поговорим позднее). Первые два параметра влияют на производительность заметно больше, нежели остальные. Причем в общем случае эти задержки для произвольного и последовательного доступа могут отличаться (и отличаются, как мы ниже увидим). Соответственно, вначале опишем ситуацию с тем, как устроена подсистема кэш-памяти в Athlon XP, а затем сравним с K8 (в данном случае авторы считают вполне разумным применять именно данную аббревиатуру, поскольку в организации кэша разницы между Opteron-ом и Athlon-ом 64 попросту нет).
Взглянем на табличные данные задержки для кэшей L1 и L2 у Athlon XP и К8 соответственно:
CPU L1 latency, тактовL2 latency, лучший случайL2 latency, худший случай
Athlon XP3 11 20
K8 3 11 16
Мы видим, что для кэша L2 опубликованы две цифры вместо одной. Какой смысл вложен в «лучший» и «худший» случаи? Для объяснения ситуации, припомним о такой особенности организации кэш-памяти процессоров AMD, как «эксклюзивность» (exclusive). Суть ее в том, что содержимое L1 не копируется в L2, а они друг друга дополняют. Таким образом, AMD говорит о суммарном объеме кэша как о L1 + L2.
Кстати, более строго было бы говорить о суммарном объеме как о L1 Data + L2, что в данном случае на 64КВ меньше. Дело в том, что, говоря о кэшировании данных, следовало бы для строгости отделять кэш команд.
Однако у такой организации кэшей есть несколько особенностей, которые необходимо знать. Прежде всего, заметим, что в Athlon XP ширина шины данных между кэшами L1 и L2 составляет 64 bit. Эти данные нам в дальнейшем понадобятся. Теперь рассмотрим на примере работы кэша у Athlon XP упомянутые особенности.
Особенность первая: поскольку в процессе работы затребованные или обработанные данные прежде всего «складываются» в кэш L1, то может возникнуть (и практически всегда возникает, кстати) нехватка места в L1. В этом случае кэш L1 должен сбросить самые «старые» или ненужные данные в L2, а уже затем принять новые данные (поскольку данные не дублируются в кэшах, мы не можем просто очистить строку кэша). Для того чтобы процесс «сбрасывания» данных происходил быстрее, в процессоре есть специальный буфер — Victim buffer, задача которого как раз и состоит в том, чтобы запомнить данные, которые будут сброшены в L2. Тем самым освобождается место в L1, которое займут свежие, только что поступившие данные. Собственно, необходимость в таком буфере возникает потому, что кэши L1 и L2 работают с разными задержками — в результате Victim buffer освобождает L1 cache от необходимости ожидать более медленный кэш L2.
Особенность вторая: Пусть, например, мы потребовали данных, которых нет в кэше L1, но они есть в кэше L2. Вполне жизненная ситуация. В этом случае задержки раскладываются следующим образом:
* На первом этапе процессор выполняет поиск данных в кэше L1, на это уходит три такта.
* На втором этапе необходимо освободить место в L1 для пересылки данных из L2. Соответственно, строка кэша в 64 байта сбрасывается в Victim buffer, освобождая место в L1. До окончания пересылки первого критического слова из L2 (после чего процессор уже может продолжать работу) необходимо еще 8 тактов.
Для читателей, обожающих подробности, укажем, что на самом деле на пересылку критического слова уходит 1 (один) такт, а оставшиеся 7 тактов уходят на собственно доступ к L2. То есть, проверке, действительно ли нужные данные лежат в кэше L2 — (L2 tag: 2 такта), и если да, то где именно — (L2 data: 2 такта), а также на доступ к шине (захват шины) — (Route/mux/ecc: 2 такта и write DC & forward: 1 такт).
Именно эти 8 + 3 такта и дают результирующую цифру в 11 тактов, которую мы и видим в таблице.
Однако, все так просто и красиво только тогда, когда Victim buffer свободен (в нем у Athlon XP может одновременно находиться восемь строк кэша). Это и есть так называемый «лучший» сценарий. Если же Victim buffer полон, все становится гораздо печальнее. Теперь нам для начала операции очистки строки кэша в L1 необходимо вначале освободить место в Victim buffer-е. На это уходит 8 тактов (перенос строки в 64 байта по шине шириной 64 бита занимает как раз 8 тактов). Затем кэш L2 два такта «отдыхает», в это время обращение к нему невозможно (собственно, речь идет не об «отдыхе», а о «turnaround», переключении режимов записи/чтения). После этого на третьем этапе начинает копироваться строка из L2 в L1, это занимает еще 8 тактов. Одновременно с этим вытесняемая из L1 строка переносится в Victim buffer. Наконец, на этапе 4 кэш L2 опять «отдыхает» два такта (на самом деле, конечно, речь идет не об «отдыхе», а о переключении режимов чтения/записи, на которое и требуется два такта). Таким образом, в нашем случае одна операция загрузки строки из кэша L2 в L1 занимает 8 + 2 + 8 + 2 = 20 тактов. Те же 20 тактов возникают и в латентности, так как операция чтения на разделяемой шине L1-L2 не может начаться, пока не будет закончена операция записи из Victim buffer.
В реальной жизни кэш почти всегда, а Victim buffer частенько, заполнены данными. Соответственно, «под нагрузкой» латентность кэша второго уровня у Athlon XP скорее тяготеет к «худшему» варианту. И уж естественно, данные особенности необходимо учитывать, если мы стремимся добиться максимальной производительности от этой архитектуры. После этого вполне резонно может возникнуть вопрос — а зачем же AMD вообще связывалась такой технологией организации кэша, как exclusive? Тут напомним, что размер кэша L1 для Athlon XP составляет 128КВ, а L2 — 256КВ (позднее 512КВ). Соответственно, терять половину объема на тривиальное дублирование содержимого было бы крайне неразумно! Не говоря уже о том, что, по оценкам AMD, выгода от большого кэша L1 превышает убытки от более сложной организации взаимодействия между L1 и L2 cache. Кстати, именно такая организация кэш-памяти и позволила, например, выпустить процессор Duron, у которого L2 cache был 64КВ, то есть вдвое меньше L1. В случае традиционной inclusive архитектуры выпуск процессора с таким соотношением объемов был бы бессмысленным.
Соответственно, учитывая, что AMD по-прежнему является приверженцем exclusive архитектуры, достаточно разумным способом улучшить ситуацию «под нагрузкой» выглядит расширение шины данных между L1 и L2. Intel в ядре Coppermine сделала это, введя технологию ATC (Advanced Transfer Cache), одна из основных особенностей которой — 256 bit шина между L1 и L2. Отсюда понятен интерес, который мы проявляли к ширине шины еще в прошлой статье.
Кстати, небезынтересен следующий факт — из всех предыдущих рассуждений у читателя может сложиться впечатление, что «exclusive cache» это редкая гадость. Это не так — данная технология является особенностью, а не недостатком. В некотором смысле в этом впечатлении «виноваты» тесты, которые специально пишутся таким образом, чтобы создать большую нагрузку для шины L1-L2. AMD совершенно справедливо утверждает, что в реальных приложениях таких ситуаций, которые бы демонстрировали «несостоятельность» эксклюзивной технологии организации кэша, практически не возникает. Ну а то, что по теоретической пропускной способности кэш второго уровня у К7/К8 проигрывает кэшу Pentium 4, связано попросту с разной идеологией этих архитектур. Таким образом, не стоит поддаваться на «магию цифр», и делать преждевременные выводы.
И еще одно замечание — вообще говоря, варианты организации кэшей отнюдь не ограничиваются вариантами exclusive и inclusive. К примеру, данные в кэше первого и второго уровней могут обновляться по совершенно отличным друг от друга алгоритмам, что делает взаимодействие кэшей еще более сложным…
Однако вернемся к вопросу о ширине шины L1-L2. Перед тем, как мы рассмотрим результаты синтетических тестов, которые и дали нам ответ на этот вопрос, необходимо будет разобраться с такой характеристикой кэша, как степень ассоциативности. Как известно, кэш, вообще говоря, может различным образом отображать памяти. Можно выделить частично- и полно-ассоциативные, кэш «прямого отображения» — все эти разновидности кэша отличаются тем, каким именно образом кэш отображает содержимое памяти. Кроме того, при различной организации кэш обновляет свое содержимое, исходя из разных алгоритмов. Впрочем, к степени ассоциативности это отношения не имеет.
Наиболее распространенным в данный момент среди процессорных архитектур является частично-ассоциативный кэш («partial associative», иногда этот термин переводят как наборно-ассоциативный) с тем или иным количеством «каналов» (либо «областей», либо «наборов», достаточно трудно перевести английский термин «n-way»). Фактически, кэш со степенью ассоциативности n-way может отображать содержимое данной строки памяти на каждую из n своих строк. Этот вариант является разумным компромиссом между полностью ассоциативным («full associative») кэшем, и кэшем «прямого отображения». Первый может отображать содержимое любой области памяти в любой области кэша, но при этом крайне сложен в схемотехнике. Собственно, за всю историю, насколько нам известно, full associative cache применялся всего один (!) раз — в микропроцессоре Cyrix Cx686 в качестве L1 кэша для кода и его размер составлял всего 256 байт (8 строк!). Второй заметно проще, но и менее эффективен, так как данные из разных областей памяти могут конфликтовать из-за единственной строки кэша, где они только и могут быть размещены. В архитектурах К7 и К8 применяется 16-канальный частично-ассоциативный кэш второго уровня.
Теперь посмотрим, каким вообще образом можно было бы измерить ширину вышеупомянутой шины. Например, если начать чтение из L2 в L1, то это должно привести к тому, что вытесненные из L1 данные должны будут попасть в L2, поскольку размер L1 не бесконечен. Соответственно, в идеальном случае (пока не будем спорить, насколько он достижим) шина L1-L2 окажется загружена как востребованными нами данными, так и теми данными, которые выселяются из L1 в L2. Если предположить, что никаких потерь пропускной способности нет, то тогда максимальная скорость чтения/обмена, которую мы можем получить таким способом, должна равняться 64bit/2, то есть 4 байта за такт. Если нам удастся превзойти данный показатель, это может служить указателем на то, что данная шина шире, чем 64 bit. Правда, есть один нюанс — дело в том, что, если взаимодействие кэшей не полностью удовлетворяет условию эксклюзивности данных, то мы можем получить ситуацию, когда вытеснения данных происходить не будет. Такая ситуация требует дополнительного изучения, и при первой возможности оно будет проведено. Но показательным в любом случае будет скорость последовательного чтения массива размером больше L2, но меньше L2+L1Data (от 1024 до 1088 килобайт для K. Если кэш работает неэксклюзивно, то часть данных будет вытеснена в оперативную память, и скорость чтения упадет. Если же высокая скорость чтения сохранится, это будет означать эксклюзивность работы кэша и пересылку удвоенного количества данных (как загружаемых в L2 из L1, так и возврат «выселенных» из L1 в L2). Именно на этом участке превышение средневзвешенной скорости над цифрой 4 байта за такт (то есть более 8 байт в обоих направлениях) будет означать более широкую, нежели 64 bit, шину!
С другой стороны, если у К8 более широкая, нежели 64 bit, шина, то тогда считывание одной строки кэша (64 байта) должно происходить за меньшее количество тактов. Естественно, имеет смысл делать ширину шины такой, чтобы прочитать строку кэша за целое число тактов — то есть 128 bit либо 256 bit (ясно, что более широкие варианты слишком нереальны, да и неэффективны, по правде говоря). Возможен еще смешанный вариант, когда у нас есть две шины по 64 bit (либо экзотические варианты, когда есть шина 128 bit в одну сторону, и 64 bit в другую). Фактически, нет особого смысла в ассиметричной шине — посему можно рассчитывать на следующие варианты:
1. 64 bit, шина не изменилась
2. 128 bit (либо 256 bit), ширина шины увеличена
3. 64 bit + 64 bit, либо 128 bit + 128 bit, более широкие варианты маловероятны.
Следовательно, надо попробовать придумать методику, которая бы позволила отличить эти случаи между собой.
Для проверки варианта «имеет ли место быть там шина шириной 128 бит» начнем читать 64-байтную строку кэша «по кругу», с различных мест строки. Попутно будем замерять, какое количество тактов потребуется на загрузку каждого из составляющих ее 4-байтовых слов (естественно, не все так просто, есть большое количество факторов, которые приходится учитывать). Если считывание идет по 16 байт (шина 128 bit), то между загрузкой первого и последнего 4-байтного слова строки должно пройти 4 такта, кроме того, начиная читать строку, скажем, с третьего слова, мы бы получили начало строки сразу же или почти сразу же. Однако приходят они в конце «круга» на восьмом такте, как и положено при 64 битной шине! Если выразить это все более простым способом, то кэши обмениваются друг с другом кусками данных («словами»), равными ширине соединяющей их шины. Читая строку кэша с разных мест, «не по порядку», мы получаем разное время. Сдвигая начальную позицию, и сравнивая время прочтения всей строки, мы определяем размер слова этой шины. Тестирование по этому методу привело нас к выводу, что считываются «слова» размером 64 bit, то есть шина имеет ширину 64 bit.
Тем не менее, тест области между 1024 и 1088 килобайтами показал, что результирующая производительность превышает 8 байт/такт, что, вкупе с доказательством отсутствия 128 битной шины в любом ее виде, приведенном в предыдущем абзаце, фактически оставляет только вариант 3. Итак, можно констатировать, что в архитектуре К8 AMD модернизировала шину L1-L2 cache. Теперь вместо одной двунаправленной шины шириной 64 bit мы получили две встречных шины по 64 бита (64 + 64), что сильно снижает вероятность возникновения «затора» в этом месте. Неплохо! Кстати, это не замедлило сказаться на низкоуровневых тестах — скорость кэша второго уровня выросла как минимум на четверть при тех же частотах. Не менее важно то, что теперь снижены (собственно, практически полностью нивелированы) отрицательные эффекты от «перегруза» шины L1-L2, то есть теперь вероятность возникновения «худшего случая» сведена к минимуму, кроме того, заметно снижена латентность в «худшем случае».
реклама
Лента материалов
Соблюдение Правил конференции строго обязательно!
Флуд, флейм и оффтоп преследуются по всей строгости закона!
Комментарии, содержащие оскорбления, нецензурные выражения (в т.ч. замаскированный мат), экстремистские высказывания, рекламу и спам, удаляются независимо от содержимого, а к их авторам могут применяться меры вплоть до запрета написания комментариев и, в случае написания комментария через социальные сети, жалобы в администрацию данной сети.
Сейчас обсуждают