Экспериментируем с TG68 - лучший кэш ч.1
Предлагаю вам перевод цикла Experimenting with TG68 Part 12a – a better cache автора Alastair M. Robinson.
Проект TG68MiniSOC до сих пор использовал очень простой кэш для процессора. Контроллер SDRAM настроен на использование пакетов из четырех слов, поэтому кэш просто хранит каждый полный пакет. При такой схеме, когда данные считываются последовательно из оперативной памяти, только одно чтение из четырех должно будет ждать контроллер SDRAM. Это самый простой из возможных примеров кэша с прямым отображением, с одной кэш-линией.
Однако есть много возможностей для улучшения: очень распространенным сценарием является повторный запуск фрагмента кода в коротком цикле, поэтому кэш, достаточно большой, чтобы вместить весь цикл, может существенно повлиять на производительность.
Самый простой способ увеличить кэш-память-добавить больше кэш-линий, однако этот наивный подход имеет ряд недостатков.
Простая реализация single-cacheline хранит кэшированный адрес и данные в регистрах. Это прекрасно работает для одной кэш-линии, но по мере добавления объем ресурсов, используемых для хранения, увеличивается довольно быстро.
Когда существует несколько кэш-линий, должен существовать метод определения того, какая строка содержит какие данные. Самый простой подход – использовать несколько битов адреса, чтобы определить, какую кэш-линию следует использовать, поэтому, если бы у нас было, скажем, 16 доступных кэш-линий, мы бы, возможно, использовали младшие 4 бита адреса для выбора кэш-линии. Как и первоначальная простая реализация, это будет прямой сопоставленный кэш. Недостатком является то, что если рабочий набор содержит две ячейки памяти, каждая из которых сопоставлена с одной и той же кэш-линией, кэш будет часто очищать одну, чтобы освободить место для другой.
В качестве альтернативы мы могли бы предоставить кэшу полную свободу выделения кэш-линий, основываясь, например, на том, какие кэш-линии дольше всего не запрашивались. Это был бы полностью ассоциативный кэш, и логика, необходимая для достижения этой цели, была бы довольно сложной.
Обычно используется компромисс что-то между этими двумя подходами, и для проекта TG68MiniSOC я собираюсь использовать 2-полосный ассоциативный кэш. Это похоже на подход с прямым отображением, за исключением того, что каждая ячейка памяти может быть кэширована в любой из пары кэш-линий, а не в одной предопределенной кэш-линии. Мы отслеживаем, какая из каждой пары кэш-линий была использована в последний раз, и когда другой адрес хочет использовать кэш-линию, мы удаляем запись, которая дольше всего не запрашивались (LRU).
Самый быстрый дизайн кэша будет содержать все, что хранится в регистрах. Однако это занимает слишком много места, поэтому нам приходится использовать BlockRAM. На Cyclone III у нас есть доступные блоки M9K, которые, как следует из названия, имеют размер 9kbit. Поскольку наши пакеты и кэш-линии имеют длину 4 слова (64 бита), один M9K может содержать 128 кэш-линий, которые мы будем рассматривать как два перекрывающихся набора из 64 кэш-линий. Поскольку процессор считывает данные в 16-битными кусками, мы будем хранить каждую кэш-строку в виде четырех индивидуально адресуемых 16-битных слов.
Нам также нужно хранить метаданные о кэш – линиях (адрес, к которому они относятся, и флаг LRU), иначе известный как тег, поэтому мы будем использовать для этого второй M9K. Чтобы убедиться, что у нас есть место для тега, флага LRU и для флага актуальности, мы сделаем BlockRAM шириной 18 бит, а не 16; тот факт, что BlockRAM имеют размер 9K, а не 8K, означает, что мы можем сделать это без использования дополнительных ресурсов.
Итак, как мы решаем, какую кэш-линию использовать для данного адреса? Опять же, мы выберем самый простой возможный маршрут и разберем адрес следующим образом:
- Bit 0 не имеет значения, потому что мы работаем c 16-битными словами, а процессор адресует байты с помощью сигналов UDS/LDS.
- Bits 2:1 определяют, какое из четырех слов кэш-линии нас интересуют.
- Bits 8:3 определяют шестибитный адрес в BlockRAM, который будет содержать эту кэш-линию. Две кэш-линии,которые мы можем выбрать,будут иметь адреса {1'b0, addr[8:3]} и {1;b1, addr[8:3]} соответственно.
- Bits 25:9 должны храниться в теге, что, оказывается, не проблема, так как у нас есть 18-битные слова. Самый старший бит будет использоваться в качестве флага LRU “ дольше всего не запрашиваемого”. Используя эту схему, мы можем поддерживать адресное пространство размером 64 мегабайта.
Первый стаб кэша с 2 путями находится в репо, но нуждается в некотором исправлении ошибок – самое главное, поддержка записи и работа с побайтовой записью.
To be continued…
Адрес для контактов : imax9@narod.ru
Если вам понравились мои работы и вы желаете поддержать сайт - сделайте дотацию.
При копировании статьи – обязательна ссылка на авторство и источник. Без разрешения автора копирование запрещено.
© Максим Ильин 2022г.