К. Касперски - Техника оптимизации программ, Эффективное использование памяти (1127752), страница 51
Текст из файла (страница 51)
В современных процессорах семейства х86 встречаются исключительно стратегии Г1ГО и 1 К(), частотный же анализ ввиду сложности его реализации в них не используется. Глава 3 25б Согласование интерфейсов процессора и контроллера памяти "Ячейка памяти" в понятии современных процессоров представляет как правило байт или двойное слово. С другой стороны, минимальной порцией обмена с физической оперативной памятью является пакегп, состоящий по меньшей мере из четырех б4-разрядных ячеек. Здесь можно провести аналогию с оптовой торговлей — производитель не отпускает товар по штукам и если нам, положим, требуется один карандаш, мы все равно вынуждены приобретать целую упаковку. Естественно, до той поры, пока остальные карандагци не будут реально востребованы (конечно, если они вообще будут востребованы), их необходимо где-то хранить.
Решение: извлечь один-единственный карандаш из упаковки и выбросить остатки — слишком нерационально, поэтому здесь не рассматривается. Тем более, что подходящее хранилище для пакетов данных у нас есть — это кэш. Получив пакет данных со "склада", пардон, загрузив их из основной оперативной памяти, кэш позволяет процессору обрабатывать эти данные с любой разрядностью. Именно этим, кстати, объясняется выбранная стратегия загрузки данных (см.
разд, "Обеспечение быстрого доступа к интенсивно испольэуемыл~ данным" этой главы). Кзш-контроллер вынужден помешать в сверхоперативную память все ячейки, к которым происходит обращение, уже хотя бы потому, что выкидывать их, как карандаши в приведенном выше примере, было бы крайне нерационально. Упреждающая загрузка данных Существует несколько стратегий загрузки данных из основной оперативной памяти в кзш-память. Простейший алгоритм загрузки, называемый загрузкой ио требованию (оп дешапа), предписывает обращаться к основной памяти только после того, как затребованных процессором данных не окажется в кзше (т. е., попросту говоря, после возникновения кэш-промаха).
В результате, в кэше окажутся действительно именно те данные, которые нам нужны (и зто плюс!), однако при первом обращении к ячейке, процессору придется очень долго ждать — приблизительно 20 тактов системной шины, если не дольше, — а вот это минус! Стратегия спекулятивной (вреси!вате) загрузки, напротив, предписывает помещать данные в кэш задолго то того, как к ним произойдет реальное обращение. Откуда же кэш-контроллер может знать, какие именно ячейки памяти потребуются процессору в ближайшем будущем? Ну, разумеется, наверняка знать он этого, конечно, не может, но почему бы ему не попробовать просто угадать? Алгоритмы угадывания. Алгоритмы угадывания делятся на интеллектуальные и неинтеллектуальные.
Типичный пример неинтеллектуального алгоритма— опереэкающав загрузка. Исходя из предположения, что данные из оператив- Кэш 257 ной памяти обрабатываются последовательно в порядке возрастания адресов, кэш-контроллер, перехватив запрос на чтение первой ячейки, в порядке собственной инициативы загружает некоторое количество ячеек, последуюшнх за ней. Если данные действительно обрабатываются последовательно, то остальные запросы процессора будут выполнены практически мгновенно, ведь запрошенные ячейки уже присутствуют в каше! Следует заметить, что стратегия опережающей загрузки возникает уже в силу необходимости согласования разрядности оперативной памяти и процессора (см.
разд. "Согласование интерфейсов процессора и контроллера памяти" этой главы). Серьезный минус опережающей (и вообще неинтеллектуальной) загрузки состоит в том, что алгоритм обработки данных дапеко не всегда совпадает с алгоритмом их загрузки и зачастую ячейки памяти востребуются процессором не в том порядке, в котором кэш-контроллер запрашивает их из основной памяти. Как следствие — мы имеем значительное падение производительности, поскольку данные были загружены вхолостую. Интеллектуальный кэш-контроллер предсказывает адрес следующей запрашиваемой ячейки не по слепому шаблону, а на основе анализа предыдущих обращений.
Исследуя последовательность кэш-промахов, контроллер пытается установить, какой именно зависимостью связны ее элементы и, если это ему удается, предвычисляет ее последуюшие члены. Если обрашение к памяти происходит по регулярному шаблону, интеллектуальная стратегия спекулятивной загрузки при благоприятном стечении обстоятельств может полностью ликвидировать задержки, возникающие при ожидании загрузки данных из основной памяти.
До недавнего прошлого интеллектуальные кэш-контроллеры использовались разве что в суперкомпьютерах и высокопроизводительных рабочих станциях, но теперь они реализованы в процессорах Реп!)цпт-4 и АМЕ) Аг)з!оп ХР (см. раэд. "Аппаратная предвыборно в микропроцессоре Р-4" этой главы). Стратегии поиска данных. В соответствии с выбранной стратегией загрузка данных из памяти может начинаться либо после фиксации кэш-промаха !стратегия йоо!с "эпгоядй), либо осуществляться параллельно с проверкой наличия соответствующей копии данных в сверхоперативной памяти и прерываться в случае кэш-попадания !стратегия Евон Аяи1е).
Последнее сокращает накладные расходы на кэш-промахи, уменьшая тем самым латентность загрузки данных, но зато увеличивает энергопотребление, что в ряде случаев оказывается неприемлемо большой платой за в обшем-то довольно незначительную прибавку производительности. Отложенная запись данных Наличие временного хранилища данных позволяет накапливать записываемые данные и затем, дождавшись освобождения системой шины, выгружать их в оперативную память "одним махом". Это ликвидирует никому не нуж- Глава 3 гвв ные задержки и значительно увеличивает производительность подсистемы памяти (подробнее об этом см.
равд. "Политики записи и поддержка когерентности" этой главы). Механизм отложенной записи в процессорах семейства х86 реализован начиная с Репбшп и АМП Кб. Более ранние модели были вынужлены непосредственно записывать в основную память кажлую модифицируемую ячейку, что серьезно ограничивало их быстродействие. К счастью, сегодня такие процессоры практически не встречаются и об этой проблеме уже можно забыть. Организация каша Для упрощения взаимодействия с оперативной памятью (и еше по ряду других причин) кэш-контроллер оперирует не байтам, а блоками данных, соответствующих размеру пакетного цикла чтения/записи (си.
раэд. эвэаимодействие пагпятп и процессора" главы 2). Программно кзш-память представляет собой совокупность блоков данных фиксированного размера, называемых кэа-линейками (согде-Впе) или кэш-строками. Каждая кэш-строка полностью заполняется (выгружается) за один пакетный цикл чтения и всегда заполняется (выгружается) целиком.
Даже если процессор обращается к одному байту памяти, кэш-контроллер инициирует полный цикл обращения к основной памяти и запрашивает всеь блок целиком. Причем, адрес первого байта кэш-линейки всегда кратен размеру пакетного цикла обмена. Другими словам: начало кэш-линейки всегла совпадает с началом пакетного цикла. Поскольку объем кэша много меньше объема основной оперативной памяти, каждой кзш-линейке соответствует множество ячеек кэшируемой памяти, а отсюда с неизбежностью следует, что приходится сохранять не только содержимое кзшируемой ячейки, но и ее адрес.
Для этой пели каждая кэшлинейка имеет специальное поле, называемое тэгои. В таге хранится линейный и(или физический адрес первого байта кэш-линейки. Следоавтельно, кэш-память фактически является ассоциативной папнтью (аээос(айте тетогу) по своей природе. В некоторых процессорах (например, в млалших моделях процессоров Репгшгп) используется только один набор тэгов, хранящих физические адреса.
Это удешевляет процессор, но для преобразования физического адреса в линейныи требуется по меньшей мере олин дополнительный такт, что снижает производительность. Другие же процессоры (например, АМ0 Кб) имеют два набора тэгов для хранения физических и линейных адресов соответственно. К физическим гегам процессор обращается лишь в двух ситуациях: при возникновении кэш-промахов (в силу используемой в процессорах семейства х86 схемы адресации, когда одна и та же ячейка может иметь множество линейных алре- Кзш 259 сов, и потому несовпадение линейных адресов еще не свидетельство промаха) и при поступлении запроса от внешних устройств (в т. ч. и других процессоров в многопроцессорных системах): имеется ли такая ячейка в кэшпамяти или нет (си.
раэд. "Протокол МЕХI" этой главы). Во всех остальных случаях используются исключительно линейные тэги, что предотвращает необходимость постоянного преобразования адресов. Доступ к ассоциативной памяти, в отличие от привычной нам адресной памяти, осуществляется не по номеру ячейки, а по ее содержанию, поэтому такой тип памяти еще называют сол!еш аддгегэед глеглогу. Кэш-строки, в отличие от ячеек оперативной памяти, не имеют адресов и могут нумероваться в произвольном порядке, да и то чисто условно.