null

Виртуальная память на sun'ках: SPARC64 и хэшированная таблица страниц

Преобразование виртуальных адресов на SPARC-системах вскользь затрагивается на довольно годном курсе Solaris Internals (в своё время он хорошо раскидал кашу в голове по нужным полкам).  Но, на мой взгляд, эта тема достойна отдельного внимания, ибо отличия от привычного многим подхода x86 очень существенные.
 
Код приложений (да и ядра в большинстве случаев) обращается в память по виртуальным адресам. Они преобразуются в физические адреса путём замены номера виртуальной страницы (старшие биты адреса) на номер соответствующей физической страницы. Точно также как и в х86, в SPARC’овых процессорах имеется отдельных кеш TLB, который используется для быстрого преобразования адресов.  На этом, пожалуй, сходство и заканчивается. Появившийся в UltraSPARC I аппаратный блок работы с памятью назывался Spitfire MMU, а модуль ядра Solaris для работы с ним - spitfire-mmu.  Основные отличия:
 
  • Во-первых, в SPARC отсутствует “hardware page walker”, т.е. в случае TLB-промаха управление передаётся операционной системе и наполнение TLB и замена в нём отдельных строчек происходит явным образом программно. В лагере Intel/AMD “page walker” аппаратный (часть блока MMU) и он сам бродит по таблицам страниц в поисках необходимой записи, а ОС вызывается в случаях нарушения прав доступа к странице или отсутствии валидной записи.  Казалось бы, о каком быстродействии может идти речь при программной обработке TLB-промахов, но об этом позже.
  • Во-вторых, в SPARC давным-давно есть понятие контекст и его тег, поэтому необходимость полностью сбрасывать TLB кэш при смене контекста отсутствует. В базовой архитектуре х86 при записи в регистр cr3 нового значения адреса таблицы страниц TLB очищается автоматически. В нём остаются только записи с меткой Global, т.е. страницы ядра. Конечно, уже есть плюшки типа ASID и PCID, но реализации AMD и Intel несовместимы между собой.
  • Ну а в-третьих, таблица страниц устроена совсем другим образом.
А теперь немного цифр для SPARC64 VII. Это вам не последний писк моды SPARC M6, но не такие уж и дрова:
  • Поддерживаемые размеры страниц: 8KiB, 64KiB, 512KiB, 4MiB, 32MiB, 256MiB
  • Раздельный TLB для кода и данных: ITLB и DTLB.
  • Полностью ассоциативный прозрачный кэш L1 TLB: uITLB и uDTLB.
  • Кэш L2 TLB: полностью ассоциативный по 32 записи (fITLB и fDTLB) + кэш на 2048 записей с уровнем ассоциативности 2 (sITLB и sDTLB). ОС отвечает за загрузку записей именно в L2 TLB.
Отдельная запись в кэше определяет расположение одной виртуальной страницы в физической памяти и называется TTE (Translation Table Entry). TTE состоит из двух 64битных частей: тэга и данных.
Ну тут всё просто: поиск осуществляется по тегу состоящему из номера контекста и номера виртуальной страницы (VA). При совпадении, для преобразования адреса используется информация из Data – номер физической страницы (PA), права доступа (Prot) и др. При размере страниц >8Kib, младшие биты PA и VA могут игнорироваться. Для соответствия спецификации SPARC JPS1 процессор обязан иметь размер физического адреса не менее 43 bit. Конкретный процессор может иметь больший размер PA за счёт использования поля Impl. Dep. Физический адрес SPARC64 VII составляет 47 бит (адресное пространство до 128TiB).
 
В случае TLB промаха, управление передаётся в ОС соответствующему обработчику прерывания. В принципе, далее ОС может делать что угодно для поиска физического адреса виртуальной страницы, вызвавшей прерывание. Однако разумно предполагается, что сначала она воспользуется возможностями процессора по ускорению этого поиска в специальной структуре TSB (Translation Storage Buffer). Для связки SPARC + Solaris 10 преобразования адреса выглядит следующим образом:
Набор структур hme_blks целиком описывает одно виртуальное адресное пространство и организован в виде хэшированной таблицы с цепочками. Для каждого процесса существует свой набор таких структур. Кроме этого у каждого процесса имеется таблица TSB, располагающаяся в основной памяти и используемая в качестве программно-управляемого кэша. Туда помещается ограниченное количество записей о расположении виртуальных страниц. Одна строка TSB занимает 128 бит и по содержимому практически совпадает с TTE, хранящемуся в TLB.
 
После TLB промаха, ОС попытается найти запись о запрошенном виртуальном адресе в TSB. Если запись найдена, то ОС загрузит её в TLB, иначе попытается найти её в hme_blks. Сама TSB может иметь разный размер. В Solaris 10 для пользовательских процессов под неё выделяется 128KiB или 512KiB. Промахи TLB довольно частое явление, поэтому поиск в TSB должен быть очень быстрым. За счёт чего же это возможно?
 
При каждом переключении контекста процесса, ядро обновляет специальный регистр, в который записывается адрес и размер текущей таблицы TSB. При TLB промахе процессор автоматически вычисляет адрес, по которому может располагаться необходимая запись в TSB. Например, для 8KiB страниц и shared типе TSB формула выглядит так:
TSB_Extension – адрес начала TSB
VA – виртуальный адрес
TSB_Hash зависит от номера контекста.
Размер TSB составляет 2^N записей.
 
Упрощённо, номер записи определяется младшими битами номера виртуальной страницы:
 
Если опустить номер контекста, то формула будет соответствовать размещению в стандартном кэше прямого отображения. Таким образом, если ОС будет помещать записи в TSB согласно правилу прямого отображения, то для поиска записи необходимо будет всего лишь прочитать из памяти строку tsbe по сгенерированному процессором адресу, и сравнить текущий контекст и номер запрашиваемой страницы с тэгом. В случае совпадения необходимый номер физической страницы получается найден за (примерно) одно обращение в память.  Аппаратно этот адрес может генерироваться только для страниц размером 8KiB и 64KiB. Несложно посчитать, что с помощью TSB можно покрыть 64MiB при маленьком TSB и 8KiB странице и 2GiB при странице 64KiB и большом TSB(512KiB).  Однако процессором SPARC64 VII аппаратно поддерживается гораздо большие TSB, вплоть до 2^24 записей.
 
Желающие окунуть сознание в дебри подробностей, могут удовлетворить свои хотелки заморскими мануалами по архитектуре SPARC, в целом по SPARCv9 и в частности по SPARC64 VII. Глядеть в приложение F "Memory Management Unit"
Next

Являюсь инженером компании Tune-IT. Проявляю интерес к:

  • вопросам производительности ВС
  • VoIP и Asterisk
  • железу SUN
  • Solaris