Сегодня кэш-память - неотъемлемая часть любого персонального компьютера. Однако появилась она не так уж и давно, начиная с 386-ых процессоров (на самом деле идея эта имеет довольно почтенный возраст - аппаратный кэш использовался еще в таком монстре, как IBM360). Зачем же нужен кэш? Ответить на этот вопрос просто: время доступа к обычной оперативной памяти (точнее, время доступа к произвольной ячейке) составляет порядка 50-60 наносекунд. В то же время тактовая частота шины равна 66 МГц (для большинства Pentium'ов), что соответствует 15 нс. Таким образом, процессор должен простаивать несколько тактов в ожидании данных. Если же учесть, что сам процессор работает с удвоенной или утроенной частотой шины, то получается еще больше. Из сложившейся неприглядной ситуации существует два выхода: либо заставить основную оперативную память работать быстрее, что довольно трудно и дорого (хотя применение SDRAM может изменить дело). Либо использовать буферную (промежуточную) память, которая позволит сгладить резкий перепад быстродействий. Кэш-память относится как раз ко второму варианту. Это статическая память, следовательно, она построена на триггерах, которые используются и в самом процессоре. При считывании данных из оперативной памяти вначале проверяется, есть ли эти данные в кэше. Если нет, то данные считываются из памяти и одновременно загружаются в кэш (причем, не один байт, а блок, равный длине строки кэша). Если в дальнейшем процессор снова будет считывать данные из памяти, то с большой вероятностью они будут находиться в быстродействующем кэше. Таким образом, сокращается время простоев процессора. Надо отметить, что все эти операции выполняются автоматически, "прозрачно" для пользователя.
Существует несколько различных архитектур построения кэша: с прямым отображением (direct mapped), полностью ассоциативный (fully associative) и группово-ассоциативный (set-associative). Чтобы разобраться в принципах их работы, представим себе некий абстрактный микропроцессор с 12-разрядной шиной адреса (объем памяти 4 Кб) и кэшем из 16 строк по 16 байт. В случае прямого отображения (см. рис. 1, а) каждая строка памяти (16 байт) может быть помещена только в определенную строку кэша.
Рис.1а |
Например, в первую строку кэша можно помещать только первую, семнадцатую, тридцать третью и т.д. строки памяти. Таким образом при обращении по адресу 101011110001 мы должны проверить 16-ую (1111) строку кэша и если в ней находится нужная строка памяти, то считать второй (0001) байт. Как же узнать, какая именно строка записана в кэш? Для этого служит так называемый тег (tag), определяемый, в данном случае, четырьмя старшими битами адреса (1010). Он записывается в служебную область кэша, соответствующую каждой строке. При обращении к памяти адрес сравнивается с тегом соответствующей строки и затем данные выбираются либо из кэша, либо из ОЗУ. Преимущество прямого отображения - в быстроте поиска данных в кэше, поскольку требуется всего одна операция сравнения тегов. Однако если необходимо часто обращаться к данным, которые записываются в одну и ту же строку кэша (например из 2 и 18 строк памяти), то его эффективность резко падает. Кстати, с 386-ми процессорами использовался именно такой кэш.
Рис.1б |
Полностью ассоциативный кэш (рис. 1, б) - прямая противоположность прямому отображению. В этом случае любая строка памяти может записываться в любую строку кэша. При этом можно наиболее эффективно размещать в кэше данные, но зато при обращении к памяти придется сравнивать адрес со всеми существующими тегами (что приведет к усложнению схем сравнения), да и длина тега теперь будет не 4, а 8 бит. Разумный компромисс между этими решениями представляет собой группово-ассоциативный кэш (рис. 1, в).
Рис.1в |
Здесь отдельные строки кэша собраны в группы (например, по четыре строки). В таком случае тег задается только шестью старшими битами адреса, а следующие два бита определяют номер группы. Сравнение тегов производится только для определенной группы. Таким образом уменьшается количество схем сравнения и достигается более-менее эффективное размещение информации в кэше. По количеству строк в группе кэш разделяют на двухвходовый (2 way - две строки), четырехвходовый (4 way - четыре строки) и т.д. Именно группово-ассоциативная архитектура применяется в большинстве 486 процессоров и в Pentium'ах.
Но с вопросом об архитектуре кэша обычному человеку, как правило, сталкиваться не приходится, а вот загадочные надписи write-back и write trough в настройке CMOS видели, наверное, все. Что же это за зверь такой? Дело тут вот в чем: допустим, процессору требуется записать некоторые данные обратно в оперативную память. Если этих данных нет в кэше, то все просто. А если они есть? Вот тут-то и используются методы записи (а это именно они) write-back и write trough. В случае write trough предполагается существование двух правильных копий данных: в кэше и памяти. Таким образом, запись производится и туда, и туда, причем, процессор вынужден ждать завершения более длительной операции записи в ОЗУ. Кроме того, при выполнении двух операций записи сильно увеличивается нагрузка на шину. Есть здесь, однако, и свои плюсы: постоянно поддерживается целостность данных (данные в кэше и ОЗУ всегда совпадают). В случае метода write-back дело обстоит следующим образом: данные записываются только в кэш. В память они попадают только тогда, когда строка в кэше заменяется на другую. Таким образом шина разгружается, а процессор меньше простаивает. Однако при этом правильные данные содержатся только в кэше и существует вероятность их потери. Кстати, с кэшем связан еще один интересный вопрос - это алгоритм обновления строк. Обычно все ограничивается упоминанием загадочных букв LRU. На самом деле все просто - LRU обозначает минимальное предыдущее использование (Least recently used) и заключается в замене той строки, к которой не обращались дольше всего.
Ну вот, мы и разобрались с принципами работы кэша. Конечно, это далеко не все, что можно о нем рассказать, но для начала вполне достаточно. Под конец хотелось бы привести кое-какие цифры относительно влияния кэша на быстродействие компьютера. Измерения производились на компьютере с процессором AMD 5x86 - 150 MHz. Как видите, наличие внутреннего кэша очень сильно влияет на быстродействие. Влияние внешнего кэша не столь заметно, однако это объясняется тем, что в данном тесте в основном измерялась скорость процессора, а влияние кэша второго уровня (L2) начинает сказываться при работе с большими объемами данных (тест производительности системы) или при выключении внутреннего кэша. Как и следовало ожидать, установив метод записи write back (w/b), можно несколько поднять быстродействие. В общем, рекомендую поэкспериментировать.
Внутренний кэш (L1) | + | + | - | - | - | + |
Внешний кэш (L2) | w/b | w/t | w/b | w/t | - | - |
Скорость | 201 | 193.9 | 29.4 | 24.4 | 11.4 | 193.2 |
Константин
АФАНАСЬЕВ,
AKG_Monster@usa.net
Горячие темы