Существенную часть кристалла современных ЦП занимает кэш-память. Дальнейшее увеличение кэш-памяти без изменения технологических норм приведет к соответствующему увеличению кристалла. Одним из способов увеличения объема хранимой информации в кэше без увеличения объёма самого кэша является использование алгоритмов компрессии. Среди них выделяются алгоритмы Base+Delta и Base-Delta-Immediate. Данная статья посвящена реализации первого алгоритма Кэш-память состоит из кэш-строк фиксированного объема.  Кэш-строку разделяют на несколько сегментов. Нулевой сегмент называют базой. При равенстве старших бит сегментов между собой возможно сжатие с помощью разности сегмента и базы, что и называется дельтой. В зависимости от размеров базы и дельт разделяют несколько режимов B8-∆1 (Base = 8 Byte, ∆ = 1 Byte)B8-∆2B8-∆4B4-∆1B4-∆2B2-∆1 Ниже представлены примеры компрессии 32-ух байтовых кэш-строк Декомпрессия происходит с помощью суммы базы и дельт. В данном примере осуществляется компрессия в режиме B4-∆1. Исходная строка, равная 32-ум байтам, сжимается до 12-ти байт Данный алгоритм компрессии обоснован, во-первых, регулярностью расположения данных в памяти и, во-вторых, малым динамическим диапазоном значений в кэш-памяти. Объем сегментов отличается в зависимости от типа сжимаемых данных. Он может быть равен 2, 4 и 8 байтам. Использование только одного фиксированного объема сегментов может существенно повлиять на степень компрессии в худшую сторону. Например, для массива указателей объемом 4 байта оптимально использовать 4-ех байтовые сегменты, а для массива 2-ух байтовых целых чисел - сегменты объемом по 2 байта Значением базы всегда выбирается нулевой сегмент, так как поиск минимального значения базы потребует сложной логики, что существенно скажется на латентности компрессии. Более того, по заявлениям разработчиков алгоритма степень компрессии не увеличится значительно, если реализовать логику поиска базы Кэш-память имеет 16 кэш-строк объемом 64 байта, что позволяет хранить 1КБ данных без компрессии. У каждой кэш-строки помимо данных имеется бит достоверности, определяющий актуальность и достоверность данных, 8-ми байтовое поле тега, хранящий адрес младшего слова в памяти, 8 невидимых байт, о предназначении которых будет упомянуто в последующих разделах, и 3 младших бита, в которых хранится код компрессии Каждая кэш-строка имеет вход, куда подаются данные, которые можно записать, если активен управляющий сигнал WE (Write Enable). Имеется асинхронный сброс, контролируемый сигналом reset. При сбросе все биты строки заполняются нулями. Выходные данные проходят через буферы трех состояний, контролируемые сигналом OE (Output Enable). На выходе появляются данные только при активности данного сигнала. Описание кэш-строки представлено ниже Для выбора строки кэш-памяти используется 4-ех битный адрес, который внутренним декодером преобразуется в 16-ти битный one-hot код. Схема декодера описана ниже Каждая кэш-строка имеет собственные сигналы WE и OE, что позволяет работать только с одной строкой в данный момент. На вход кэш-памяти подается управляющий сигнал RD (ReaD), указывающий на осуществления операции чтения или записи. В случае его активности значению сигналов OE присваивается значение декодированного адреса, так что выходом кэш-памяти является кэш-строка с активным сигналом OE, это операция чтения. В случае, если RD неактивен, то значению сигналов OE присваиваются нули, а значению WE присваивается one-hot код, так что только одна кэш-строка захватывает данные на входе кэш-памяти, это операция записи. Кэш-память также имеет сигнал асинхронного сброса, который является единым для всех кэш-строк, позволяющий сбросить каждую строку. Схема кэш-памяти представлена ниже Бит достоверности может задавать только компрессор при передаче данных и сигнал reset. Отсутствие какой-либо кэш-когерентности связано с отсутствием необходимости при работе над кэш-компрессией Данный кэш имеет алгоритм прямого отображения. Это связано не с эффективностью, а с удобством реализации, так как для реализации кэш-компрессии не важен алгоритм ассоциативности. Для обращения в кэш следует проверить бит достоверности и сравнить поле тега с полем запроса только в одной кэш-строке, что очень удобно Мою реализацию отличает то, что кэш-память имеет традиционный вид без использования двух полей тегов, хотя и имеет небольшие модификации в виде хранении кода компресси (их можно хранить и в отдельной таблице, если нужно) и невидимых байт. Одной из проблем в реализации кэш-компрессии стоит увеличение хранимой информации. Сжимая кэш-строку, мы не можем записать что-либо в свободное пространство. В связи с этим было придумано решение в виде сжатия данных из внешнего источника и записи сжатых данных в кэш-память. Используется специальный буфер чтения, который имеет вдвое больший объём, чем кэш-строка - 128 байт. Значение буфера чтения сжимается по одному из алгоритмов компрессии и записывается в кэш-память Исходный объём Режим компрессии Сжатый объём Количество сегментов 128 Byte B8-∆1 24 Byte 16 128 Byte B8-∆2 40 Byte 16 128 Byte B8-∆4 72 Byte 16 128 Byte B4-∆1 36 Byte 32 128 Byte B4-∆2 68 Byte 32 128 Byte B2-∆1 66 Byte 64 Максимальный объем сжатых данных равен 72-ум байтам. В связи с этим были добавлены 8 невидимых байт в каждую кэш-строку, которые будут нужны только при использовании алгоритмов, превышающие порог в 64 байта Наша система оперирует 64 битными словами, поэтому кэш-строка без компрессии имеет 8 слов. Но с компрессией кэш-строка может хранить в два раза больше слов - 16. Причем режим компрессии не играет роли Особым случаем является невозможность компрессии. Тогда можно было бы записать данные буфера в две кэш-строки, но это может привести к уничтожению сжатых данных в соседней кэш-строке, поэтому разумнее отбросить некоторые слова буфера чтения и записать оставшиеся в кэш-память. Если степень компрессии в данном приложении будет минимальной, если это может отрицательно повлиять на производительность, можно отключить компрессию с помощью сигнала CON (Compression On). В таком режиме кэш-память ведет себе как обычная. На вход компрессора подаются данные из основной оперативной памяти. Эти данные записываются в буфер чтения. Буферов чтения может быть несколько, также может быть несколько компрессоров, если реализовать порядок последовательной записи из компрессоров. Он также имеет асинхронный сбор Биты буфера чтения проходят через компараторы, которые определяют возможность компрессии по одному из режимов. Одни компараторы сравнивают между собой младшие биты сегментов. Важно, чтобы значение младших бит базы было меньше или равно значениям младших бит сегментов. Достаточно трех таких компараторов для режимов B8-∆4, B4-∆2 и B2-∆1. Чтобы понять, что это так, рассмотрим следующий пример. Предположим, что значение буфера может быть сжато по алгоритму B8-∆1. Тогда значение компараторов для B8-∆4 будет полностью соответствовать значению компараторов для B8-∆1, так как на результат будет влиять только один младший байт, ведь остальные 3 байта равны Другие компараторы сравнивают старшие разряды сегментов на равенство. Если старшие разряды сегментов равны, а младшие разряды сегментов больше, либо равны младшим разрядам базы, то возможна компрессия по этому режиму. Так формируется значение сигналов bd Сигналы bd подаются на схему приоритета, чтобы не возникал конфликт в случае, когда компрессия может быть осуществлена разными способами. Между собой режимы не имеют приоритетов друг над другом, но они все приоритетнее отсутствия компрессии. Старший бит означает отсутствие компрессии, поэтому приоритет расставлен от младшего разряда к старшему. Ниже представлена схема приоритета. Данное значение используется при компрессии. В зависимости от установленного режима компрессии вычисляется значение выхода компрессора. В случае удачной компрессии в кэш-строку записываются следующие данные: бит достоверности (равный 1), поле тега (копируется с буфера чтения), сжатые данные, пустое пространство (если есть) и код компрессии Поле кода компрессии имеет три бита и вычисляется с помощью схемы, обратной схемы декодера, представленной ниже Если компрессия неосуществима, то в кэш-строку записываются старшие 8 слов буфера чтения. Если сигнал CON равен 0, что свидетельствует об отключенной компрессии, запись в кэш-строку происходит в два цикла. Когда значение T-триггера равно 1, записываются старшие слова буфера чтения. Когда значение T-триггера равно 0, записываются младшие слова буфера чтения по адресу, меньший на 1. Т-триггер представляет из себя схему, которая за каждый такт инвертирует и выводит внутренний сигнал. При асинхронном сбросе значение внутреннего сигнала становится равным 0. Её описание представлено ниже Вся схема компрессора выглядит следующим образом С пословной адресацией (64 бит) требуется 8 слов для заполнения кэш-строки объемом 64 байт. Отсюда следует, что 3 младших бита поля тега (адрес младшего слова в памяти) должны быть равны 0. А в теге запроса младшие три бита будут обеспечивать выбор слова в кэш-строке. Для выбора самой кэш-строки (адрес кэш-памяти) нужно считать следующие 4 бита (так как кэш-строк 16 = 2^4) тега запроса (при чтении), либо тега в буфере чтения (при записи) Когда включена компрессия, каждая кэш-строка может содержать 8, либо 16 слов. Тогда младшие 4 бита поля тега будут равны 0. Младшие 4 бита тега запроса будут обеспечивать выбор слова из кэш-памяти. Следующие 4 бита в теге запроса или в поле тега буфера чтения будут обеспечивать выбор кэш-строки Запись в кэш-память осуществляется только через компрессор, даже если компрессия отключена. Операция чтения (RD активен) происходит следующим образом. По тегу запроса известно, в какой кэш-строке находятся данные. Затем поле тега передается и бит достоверности вместе с тегом запроса, а также вместе с сигналом CON передаются в фильтр запросов. Там происходит сравнение старших бит поля тега и старших бит тега запроса. Младшие 3 или 4 бита (в зависимости от сигнала CON) не сравниваются по той причине, что у тега запроса они служат для выбора слова. Если равенство устанавливается, а также бит достоверности равен 1, то сигнал кэш-попадание устанавливается в 0. В противном случае данный сигнал устанавливается в 1.  Когда компрессия включена, но для строки нет режимов компрессии, отсеиваются запросы в первые 4 слова Схема фильтра запросов описана ниже Данные с кэш-памяти попадают в декомпрессор. Декомпрессия происходит путем сложения базы и дельт. Если компрессия отключена, либо для строки нет режима компрессии, то данные кэш-строки выводятся без декомпрессии. Декомпрессор реализован с помощью сумматоров, работающих параллельно. Декомпрессор представлен ниже Затем, имея адрес слова, схема WSU (Word Select UnIt) выводит одно из слов памяти на выход. Её описание представлено ниже Обращение к кэш-памяти происходит стандартным образом за тем исключением, что есть схема декомпрессии. Со сжатыми кэш-строками мы работаем также, как если бы мы работали с настоящими 128-ми байтовыми кэш-строками. Данная реализация алгоритма Base+Delta не меняет принципов ассоциативности кэш-памяти. Вся система выглядит следующим образом Здесь, помимо описанных модулей, есть ещё несколько мультиплексоров, обеспечивающих выбор правильного адреса для кэш-памяти. Стоит ещё отметить, что данные выводятся только при кэш-попадании. Значение кэш-попадания основано на инвертированном значении кэш-промаха и сигнала RD. То есть даже если кэш-попадание есть в принципе есть, считывание не произойдет, если используется операция записи В статье, как вы увидели, отсутствуют тесты. Их вы можете посмотреть у авторов-разработчиковО таких алгоритмах я узнал от других разработчиков, статью которых прикрепляю Залил на github