Синонимы в VIVT-кэше
Если бы омонимы в кэше были бы единственной проблемой, то разработчики процессоров были бы самыми счастливыми людьми на свете. Существует и вторая проблема — синонимы (synonyms, aliases), когда несколько виртуальных адресов отображаются на один и тот же физический адрес.
Вернемся к нашим баранам процессам А и Б. Предположим, что проблему омонимов мы решили каким-нибудь приличным способом, потому что каждый раз флашить кэш — это реально очень дорого!
Итак:
1. Сначала выполняется Процесс А — в кэш одна за другой загружаются Строки А0 — А3 и Общая строка 0 (помните, что у процессов А и Б одна страница общая)
2. Потом операционная система, не флаша кэш, переключает контекст
3. Начинает выполняться Процесс Б. В кэш загружаются строки Б0 — Б7.
4. Наконец, Процесс Б обращается к Общей строке 0. Эта строка уже загружена в кэш Процессом А, но процессор про это не знает, так как она фигурирует в кэше под другим виртуальным адресом (напомню, что в VIVT-кэше физических адресов нет)
5. Возникает промах кэша. Виртуальный адрес 0x00000200 транслируется в физический адрес 0x40000200, и Общая строка 0 повторно загружается в кэш. Ее расположение определяется виртуальным адресом — а адресу 0x00000200 соответствует Индекс 0 (биты 8-6) и Тэг 0x1 (биты 31-9).
6. Поскольку оба канала в наборе с индексом 0 уже заняты, приходится выкинуть одну из уже загруженных строк (А0 или Б0). Используя алгоритм LRU (Least Recently Used), кэш выкидывает Строку А0 и на ее место добавляет Общую строку 0.
В результате один и тот же кусок физической памяти находится в кэше в двух разных местах. Теперь если оба процесса изменят свою копию, а потом захотят сохранить ее в память, то один из них ждет сюрприз.
Очевидно, что эта проблема актуальна только для кэша данных либо для объединенного кэша (повторюсь, кэш команд доступен только для чтения), но решить ее гораздо сложнее, чем проблему омонимов:
1. Самый простой способ, как мы уже выяснили — флашить кэш при каждом переключении контекста (кстати, для борьбы с синонимами, в отличие от омонимов, инвалидировать кэш не нужно). Однако, во-первых, это дорого, а во-вторых, это не поможет, если процесс захочет иметь в своем адресном пространстве несколько копий одной и той же физической страницы
2. Можно выявлять синонимы аппаратно:
· Либо при каждом промахе пробегать по всему кэшу, выполняя трансляцию адреса для каждого тэга и сравнивая полученные физические адреса с тем, который получен при трансляции адреса, вызвавшего промах (и позавидуют живые мертвым!)
· Либо добавить в процессор новый блок, который будет выполнять обратную трансляцию — преобразование физического адреса в виртуальный. После этого при каждом промахе выполнять трансляцию вызвавшего его адреса, после чего при помощи обратной трансляции преобразовывать этот физический адрес в виртуальный и сравнивать его со всеми тэгами в кэше. Ей-богу, лучше бы вам просто флашить кэш!
3. Третий способ — избегать синонимов программно. Например, не использовать общие страницы. Или снова начать линковать программы в общее адресное пространство.
Дата добавления: 2018-09-24; просмотров: 384;