
Мультипроцессорная когерентность кэш-памяти
Мультипроцессорная система с разделяемой памятью состоит из двух или более независимых процессоров, каждый из которых выполняет либо часть большой программы, либо независимую программу. Все процессоры обращаются к командам и данным, хранящимся в общей основной памяти. Поскольку память является обобществленным ресурсом, при обращении к ней между процессорами возникает соперничество, в результате чего средняя задержка на доступ к памяти увеличивается. Для сокращения такой задержки каждому процессору придается локальная кэш-память. В свою очередь, оснащение каждого процессора локаль-ной кэш-памятью приводит к проблеме когерентности (обеспечения согласован-ности кэш-памяти). Система является когерентной, если каждая операция чтения по какому-либо адресу, выполненная любым из процессоров, возвращает значе-ние, занесенное в ходе последней операции записи по этому адресу, вне зави-симости от того, какой из процессоров производил запись последним.
В простейшей форме проблему когерентности кэш-памяти можно пояснить следующим образом (рис. 2.6). Пусть два процессора P1 и P2 связаны с общей памятью посредством шины. Сначала оба процессора читают переменную x. Копии блоков, содержащих эту переменную, пересылаются из основной памяти в локальные кэши обоих процессоров (рис. 2.6, а). Далее процессор P1 выполняет операцию увеличения значения переменной x на единицу. Так как копия пере-менной уже находится в кэш-памяти данного процессора, произойдет кэш-попадание и значение x будет изменено только в кэш-памяти 1. Если теперь процессор P2 вновь выполнит операцию чтения x, то также произойдет кэш-попадание и P2 получит хранящееся в его кэш-памяти «старое» значение x (рис. 2.6, б).
Рис. 2.6. Иллюстрация проблемы когерентности памяти: а – содержимое памяти до изменения значения x; б – после изменения.
Поддержание согласованности требует, чтобы при изменении элемента данных одним из процессоров соответствующие изменения были проведены в кэш-памяти остальных процессоров, где есть копия измененного элемента дан-ных, а также в общей памяти. Аналогичная проблема возникает и в однопроцес-сорных системах, где присутствует несколько уровней кэш-памяти. Здесь требу-ется согласовать содержимое кэшей разных уровней.
В решении проблемы когерентности выделяются два подхода: программ-ный и аппаратный.
4. Программные способы решения проблемы когерентности
Программные приемы решения проблемы когерентности позволяют обойтись без дополнительного оборудования или свести его к минимуму. Задача возлагается на компилятор и операционную систему. Привлекательность такого подхода в возможности устранения некогерентности еще до этапа выполнения программы, однако принятые компилятором решения могут отрицательно ска-заться на эффективности кэш-памяти.
Компилятор анализирует программный код, определяет те совместно ис-пользуемые данные, которые могут стать причиной некогерентности, и помечает их. В процессе выполнения программы операционная система или соответст-вующая аппаратура предотвращает кэширование (занесение в кэш-память) поме-ченных данных, и в дальнейшем для доступа к ним, как при чтении, так и при записи, приходится обращаться к «медленной» основной памяти. Учитывая, что некогерентность возникает только в результате операций записи, происходящих значительно реже, чем чтение, рассмотренный прием следует считать недоста-точно удачным.
Более эффективными представляются способы, где в ходе анализа прог-раммы определяются безопасные периоды использования общих переменных и так называемые критические периоды, где может проявиться некогерентность. Затем компилятор вставляет в генерируемый код инструкции, позволяющие обеспечить когерентность кэш-памятей именно в такие критические периоды.