Управление кэшированием в x86 процессорах старших поколений
Программному управлению кэшированием просто не повезло. Концепция "прозрачного" кэша, активно продвигаемая фирмой Intel, абстрагировала программистов от подробностей аппаратной реализации кэш-контроллера и не предоставила им никаких рычагов управления. Впрочем, для достижения полной абстракции, интеллектуальности первых кэш-контроллеров все равно хватало и для системных программистов пришлось оставить крохотную лазейку, позволяя им в частности запрещать кэширование страниц памяти, принадлежащих периферийным устройствам.
До тех пор, пока подавляющее большинство приложений перемалывало компактные, многократно обрабатываемые структуры данных, стратегия загрузки кэш-линеек по первому требованию вполне справлялась со своей задачей, но с появлением мультимедийных приложений стала "буксовать". Резко возросший объем обрабатываемых данных вкупе с нашествием потоковых алгоритмов, обращающихся к каждой ячейке памяти всего лишь раз, привел к постоянным перезагрузкам кэша, ограничивая тем самым производительность системы не быстродействием процессора, а пропускной способностью оперативной памяти.
Первой этой проблеме бросила вызов фирма AMD, включив в состав набора команд 3D Now! инструкцию prefetch, позволяющую программисту заблаговременно загружать в кэш ячейки памяти, к которым он рассчитывает обратиться в ближайшем будущем. Причем, загрузка данных осуществляется без участия и остановки вычислительного конвейера! Это убивает двух зайцев сразу: во-первых, "ручное" управление кэш-контроллером позволяет выбрать оптимальную стратегию упреждающей загрузки данных, что существенно уменьшает количество кэш-промахов, а, во-вторых, с предвыборкой становится возможным загружать очередную порцию данных параллельно с обработкой предыдущей, маскируя тем самым латентность тормозов оперативной памяти!
Следом за K6, предвыборка (естественно, в усовершенствованном варианте) появилась и в процессоре Pentium-III, да не одна, а с целой свитой команд "ручного" управления кэшированием, – Intel явно не хотела отставать от конкурентов!
Совершенствование управления подсистемой памяти продолжилось и в Pentium-4. Помимо множества новых команд (таких как….), в нем реализован воистину уникальный (с появлением Athlon XP уже, увы, не уникальный) на сегодняшний день механизм аппаратной предвыборки
с интеллектуальным алгоритмом упреждающей загрузки. Анализируя порядок, в котором приложение запрашивает данные из оперативной памяти, процессор пытается предсказать (приблизительно так же, как предсказывает направление условных переходов) адрес следующей обрабатываемой ячейки, чтобы спекулятивно загрузить ее в кэш еще до того, как в ней возникнет необходимость. Естественно, при всей прозрачности аппаратной предвыборки, организовать структуры данных желательно так, чтобы процессор пореже ошибался в своих предсказаниях (а в идеале – не ошибался вообще).
При грамотном обращении команды управления кэшированием (равно как и аппаратная предвыборка) ускоряют типовые операции с памятью, по крайне мере, в три-пять раз, а в некоторых случаях и более того! К сожалению, оптимизацию кэширования невозможно возложить на плечи компилятора. Она осуществляется на уровне структур данных и алгоритмов их обработки, а оптимизировать алгоритмы компиляторы еще не научились (и маловероятно, чтобы научились в обозримом будущем). Поэтому, эту работу программистам приходится выполнять самостоятельно.