
- •Организация памяти вычислительных систем
- •Память с чередованием адресов
- •Модели архитектур распределенной памяти
- •Мультипроцессорная когерентность кэш-памяти
- •Программные способы решения проблемы когерентности
- •Аппаратные способы решения проблемы когерентности
- •Протоколы наблюдения
- •Протоколы на основе справочника
Аппаратные способы решения проблемы когерентности
Большинство из предложенных способов борьбы с некогерентностью ориентированы на динамическое (в процессе вычислений) распознавание и устранение несогласованности копий совместно используемых данных с помощью специальной аппаратуры. Аппаратные методы обеспечивают более высокую производительность, поскольку издержки, связанные с некогерентностью, имеют место только
при возникновении ситуации некогерентности. Кроме того, непрограммный подход прозрачен для программиста и пользователя [215]. Аппаратные механизмы преодоления проблемы когерентности принято называть протоколами когерентности кэш-памяти.
Как известно, для обеспечения идентичности копий данных в кэше и основной памяти в однопроцессорных системах применяется одна из двух стратегий: сквозная запись (write through) или обратная запись (write back). При сквозной записи новая информация одновременно заносится как в кэш, так и в основную память.
При обратной записи все изменения производятся только в кэш-памяти, а обновление содержимого основной памяти происходит лишь при удалении блока из кэшпамяти путем пересылки удаляемого блока в соответствующее место основной памяти. В случае мультипроцессорной системы, когда копии совместно используемых данных могут находиться сразу в нескольких кэшах, необходимо обеспечить когерентность всех копий. Ни сквозная, ни обратная запись не предусматривают такой ситуации, и для ее разрешения опираются на другие приемы, а именно: запись с аннулированием (write invalidate) и запись с обновлением (write update). Последняя известна также под названием записи с трансляцией (write broadcast).
В варианте записи с аннулированием, если какой-либо процессор производит изменения в одном из блоков своей кэш-памяти, все имеющиеся копии этого блока в других локальных кэшах аннулируются, то есть помечаются как недостоверные. Для этого бит достоверности измененного блока (строки) во всех прочих кэшах устанавливается в 0. Идею записи с аннулированием иллюстрирует рис. 11.6, где показано исходное состояние системы памяти, где копия переменной х имеется во всех кэшах (рис. 11.6, а), а также ее состояние после записи нового значениях в кэш с номером 2 (рис 11.6, б).
Если
впоследствии другой процессор попытается
прочитать данные из своей копии такого
блока, произойдет кэш-промах. Следствием
кэш-промаха должно быть занесение в
локальную кэш-память читающего процессора
корректной копии блока.
Некоторые схемы когерентности позволяют получить корректную копию непосредственно из той локальной кэш-памяти, где блок подвергся модификации. Если такая возможность отсутствует, новая копия берется из основной памяти. В случае сквозной записи это может быть сделано сразу же, а при использовании обратной записи модифицированный блок предварительно должен быть переписан в основную память.
Запись с обновлением предполагает, что любая запись в локальный кэш немедленно дублируется и во всех остальных кэшах, содержащих копию измененного блока (немедленное обновление блока в основной памяти не является обязательным). Этот случай иллюстрирует рис. 11.7.
Стратегия
записи с обновлением требует
широковещательной передачи новых данных
по сети межсоединений, что осуществимо
не при любой топологии сети.
В общем случае для поддержания когерентности в мультипроцессорных системах имеются следующие возможности:
- совместно используемая кэш-память;
- некэшируемые данные;
- широковещательная запись;
- протоколы наблюдения;
- протоколы на основе справочника.
Совместно используемая кэш-память. Первое и наиболее простое решение -вообще отказаться от локальных кэшей и все обращения к памяти адресовать к одной общей кэш-памяти, связанной со всеми процессорами посредством какой-либо коммуникационной сети. Хотя данный прием обеспечивает когерентность копий данных и прозрачен для пользователя, количество конфликтов по доступу к памяти он не снижает, поскольку возможно одновременное обращение нескольких процессоров к одним и тем же данным в обшей кэш-памяти. Кроме того, наличие разделяемой кэш-памяти нарушает важнейшее условие высокой производительности, согласно которому процессор и кэш-память должны располагаться как можно ближе друг к другу. Положение осложняется и тем, что каждый доступ к кэшу связан с обращением к арбитру, который определяет, какой из процессоров получит доступ к кэш-памяти. Тем не менее общая задержка обращения к памяти в целом уменьшается.
Некэшируемые данные. Проблема когерентности имеет отношение к тем данным, которые в ходе выполнения программы могут быть изменены. Одно из вероятных решений — это запрет кэширования таких данных. Технически запрет на кэширование отдельных байтов и слов достаточно трудно реализуем. Несколько проще сделать некэшируемым определенный блок данных. При обращении процессора к такому блоку складывается ситуация кэш-промаха, производится доступ к основной памяти, но копия блока в кэш не заносится. Для реализации подобного приема каждому блоку в основной памяти должен быть придан признак, указывающий, является ли блок кэшируемым или нет.
Если кэш-система состоит из раздельных кэшей команд и данных, сказанное тносится главным образом к кэш-памяти данных, поскольку современные подходы к программированию не рекомендуют модификацию команд программы. Следовательно, по отношению к информации в кэше команд применяется только операция чтения, что не влечет проблемы когерентности.
В отношении того, какие данные не должны кэшироваться, имеется несколько подходов.
В первом варианте запрещается занесение в кэш лишь той части совместно используемых данных, которая служит для управления критическими секциями программы, то есть теми частями программы, где процессоры могут изменять разделяемые ими данные. Принятие решения о том, какие данные могут кэшироваться, а какие — нет, возлагается на программиста, что делает этот способ непрозрачным для пользователя.
Во втором случае накладывается запрет на кэширование всех совместно используемых данных, которые в процессе выполнения программы могут быть изменены.
Естественно, что для доступа к таким данным приходится обращаться к медленной основной памяти и производительность процессора падает. На первый взгляд, в варианте, где запрещается кэширование только управляющей информации, производительность процессора будет выше, однако, прежде чем сделать такой вывод, нужно учесть одно обстоятельство. Дело в том, что для сохранения согласованности данных, модифицируемых процессором в ходе выполнения критической секции программы, строки с копиями этих данных в кэш-памяти при выходе из критической секции нужно аннулировать. Данная операция носит название очистки кэшпамяти (cache flush). Очистка необходима для того, чтобы к моменту очередного входа в критическую секцию в кэш-памяти не осталось "устаревших"- данных. Регулярная очистка кэша при каждом выходе из критической секции снижает производительность процессора за счет увеличения времени, нужного для восстановления копий в кэш-памяти. Ситуацию, можно несколько улучшить, если вместо очистки всей кэш-памяти помечать те блоки, к которым при выполнении критической секции было обращение, тогда при покидании критической секции достаточно очищать только эти помеченные блоки.
Широковещательная запись. При широковещательной записи каждый запрос на запись в конкретную кэш-память направляется также и всем остальным КЭШам системы. Это заставляет контроллеры кэшей проверить, нет ли там копии изменяемого блока. Если такая копия найдена, то она аннулируется или обновляется, в зависимости от применяемой схемы. Метод широковещательной записи связан с дополнительными групповыми операциями с памятью (транзакциями), поэтому он реализован лишь в больших вычислительных системах.
На двух последних возможностях поддержания когерентности в мультипроцессорных системах остановимся более подробно.