Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Суперкомпьютеры и системы. Мультипроцессоры. Учебное пособие
.pdf
го элемента данных и является ли она «чистой» или «грязной» (модифицированной). Поскольку запрашивать каталог приходится при выполнении любого обращения к памяти, он должен поддерживаться высокоскоростным специализированным аппаратным обеспечением, способным обработать запрос очень быстро. На рис. 3.10 показана структура однопроцессорного узла cc-NUMA-системы, построенной на основе использования метода каталога.
Адресное пространство всей системы распределено между узлами,
и это распределение должно быть «известно» диспетчеру памяти. Самый удобный и простой вариант, когда количество узлов в системе
равно степени двойки и память распределена поровну между узлами.
Тогда старшие разряды любого адреса памяти являются номером узла.
При любом обращении к памяти диспетчер по локальной шине отслеживает вырабатываемый процессором адрес и результат обработки
этого обращения локальным кэшем. Вначале рассмотрим только операции чтения данных. Будем далее обозначать узел, запрашивающий
чтение элемента данных, как УЗ, а узел-владелец, в основной памяти
которого элемент данных хранится постоянно, как УВ, и узел, в кэше
которого находится копия значения или модифицированное значение
элемента, как УК.
Рис. 3.10. Узел cc-NUMA-системы на основе каталога
Процессор
Каталог
Локальный
кэш
Диспетчер
памяти
Коммутатор
Модуль
памяти
узла
Модуль
памяти
узла
Если требуемый элемент данных находился в локальном кэше (попадание в кэш), то кроме передачи его значения в процессор больше
41

ничего не делается. При промахе кэша диспетчер по старшим разрядам
адреса определяет, какой узел является владельцем элемента данных, и
выбирает сведения о его фактическом местонахождении из каталога
этого узла (нужный каталог может находиться прямо в запрашиваемом
узле, т. е. УЗ может совпадать с УВ).
Значение требуемого элемента данных может находиться либо в
основной памяти узла-владельца, либо, если оно было ранее выбрано
(а потом, возможно, модифицировано) каким-либо процессором, в
кэше некоторого узла УК. Заметим, что возможна и такая ситуация,
когда владелец одновременно хранит и копию в кэше, т. е. УВ совпадает с УК.
В первом случае наряду с выборкой сведений из каталога из основной памяти узла-владельца по заданному адресу выбирается значение
элемента и отправляется в запрашивающий узел. Во втором случае запрос перенаправляется в узел УК, который хранит модифицированное
значение. Из его кэша значение выбирается и через коммуникационную сеть передается в УЗ. В любом случае в каталоге узла-владельца
УВ делается отметка, что копия значения элемента теперь находится в
кэше узла УЗ. Это делается согласно принципу локальности: замечено,
что если процессор читает некоторую переменную, то с высокой вероятностью он вскоре будет читать ее заново либо вскоре выполнит запись нового ее значения. В этих случаях операции повторного доступа
к элементу данных будут выполнены быстрее, если элемент находится
в локальном, а не в удаленном кэше.
Пусть теперь процессор выполняет операцию записи нового значения в память. Согласно тому же принципу локальности элемент данных должен попасть прежде всего в локальный кэш УЗ, даже в том
случае, если при попытке записи обнаружен кэш-промах. В этом случае диспетчер памяти определяет, какая строка кэша должна быть вытеснена. Наилучшим кандидатом является любая из недействительных
строк, становящаяся теперь актуальной. Недействительными становятся все строки в момент включения электропитания системы и те строки, актуальные значения которых оказались в кэшах других узлов. Недействительная строка переводится в состояние актуальной, в нее пишется адрес основной памяти элемента данных. Отметим, что в случае
кэш-попадания при записи актуальная строка в кэше уже есть. Далее в
эту строку записывается новое значение элемента данных, а во все узлы системы рассылается сообщение о том, что этот узел стал УК по
отношению к элементу с этим адресом. Диспетчеры всех узлов прове-
42

ряют свои каталоги и кэши по этому адресу. Возможны следующие
ситуации.
1. Узел является владельцем элемента. В его каталоге отмечается,
какой из узлов теперь стал УК, эта информация будет далее использоваться при любом чтении так, как описано выше.
2. Узел хранит в локальном кэше предыдущее значение элемента
данных. Эта строка кэша диспетчером памяти узла превращается в недействительную и может использоваться для любой последующей
операции записи так, как описано выше.
3. Узел не является владельцем и не хранит копию. В этом случае
его диспетчер не делает ничего.
Если при кэш-промахе по записи в кэше нет ни одной недействительной строки, то диспетчер памяти узла выбирает одну из строк,
хранящую немодифицированную копию значения какого-либо элемента (по возможности, если строки хранят информацию о времени, истекшем с момента последнего обращения к этой строке, – самую старую). И, наконец, если все строки кэша хранят модифицированные
значения каких-либо элементов, то диспетчер памяти решает, какая из
них будет вытеснена в основную память. Решение может приниматься,
например, на основании «близости» узла-владельца этого элемента к
данному узлу по коммуникационной среде. Идеальным будет случай,
когда вытеснять надо в собственный модуль памяти, не загружая этим
коммуникационную среду системы в целом. Содержание выбранной
строки вместе с адресом передается в нужный узел, а выбранная строка теперь будет хранить модифицированное значение элемента данных. Об этом извещаются все узлы системы.
Размер памяти каталога каждого узла зависит от соотношения объема модуля памяти узла и размера строки кэша. Размер строки кэша
определяется шириной шины данных коммуникационной среды системы (или, наоборот, требует, чтобы ширина шины данных совпадала
с размером строки кэша в битах). Иначе, если ширина шины будет
меньше размера строки кэша, передача строки от узла к узлу должна
выполняться за несколько циклов работы коммуникационной среды.
При этом должны учитываться еще и ширина локальной шины узла
(максимальное количество бит данных, читаемых / записываемых процессором за одну операцию обращения к памяти). Кроме того, следует
принимать во внимание еще один аспект принципа локальности: если
процессор обратился к памяти по адресу A, то с высокой вероятностью
в ближайшее время обратится к ней по адресу A + 1. В то же время
43

чрезмерно увеличивать размер строки не следует, поскольку в некоторых случаях после обращения к элементу данных с адресом A не последует обращений к памяти по ближайшим последующим адресам.
Следовательно, слишком широкая строка кэша неизбежно повлечет за
собой лишние, паразитные, пересылки тех данных, которые никому не
понадобятся. Типичным компромиссом можно считать размер элемента
данных строки, равный 64 байтам. Заметим при этом, что кэш-промах
при записи может повлечь за собой выполнение операции чтения строки
целиком из памяти или кэша другого узла в том случае, если процессор
работает с данными меньшего размера, чем размер строки.
Размер одной записи каталога k в битах определяется количеством
k
K ≤ 2
узлов в системе (или, наоборот, ограничивает его). Чем больше
емкость модуля памяти и чем меньше размер строки кэша, тем большее количество записей должен хранить каталог. Если модуль памяти
узла имеет емкость 2
N
байт, а строка кэша хранит 2n байт, то каталог
должен хранить N/n записей. Например, при N = 30 (емкость модуля
памяти 1 Гбайт) и n = 6 (64 байта данных в строке) каталог должен
иметь 2
30
/ 26 = 224 = 16 777 216 записей. В этом случае для системы с
количеством узлов, меньшим или равным 256, в каждом узле нужно
иметь быстродействующую память объемом 16 Мбайт; если же количество узлов превышает 256, то объем этой памяти узла должен быть
равен 32 Мбайт.
Очевидным недостатком этого простейшего метода является то,
что любой элемент данных может быть кэширован только одним узлом. Это будет вызывать, точно так же как в UMA-системах, массу ненужных дополнительных пересылок данных по коммуникационной
среде. Чтобы строки можно было кэшировать в нескольких узлах, требуется расширить каждую запись каталога и усовершенствовать способ поиска узлов (для того чтобы объявлять недействительными или
обновлять при записи). Возможны различные варианты. Один из вариантов – содержать в каждой записи каталога m полей для идентификации других узлов, что позволит кэшировать каждую строку на нескольких узлах (до m узлов). Второй вариант – заменить поле номера
узла битовой картой, по одному биту на узел. Здесь нет ограничений
на количество копий, но существенно растут непроизводительные затраты. Для каждого узла каталог, содержащий 256 бит для 64-байтной
(512-разрядной) строки кэша, потребует уже 512 Мбайт быстродействующей памяти. Третий вариант – хранить в каждой записи каталога
8-разрядное поле и использовать его в качестве заголовка связного
44

списка, содержащего указатели на все копии строки кэша в разных узлах. Размеры списков могут быть разными для разных записей. При
такой стратегии также требуется много дополнительного пространства
в быстродействующей памяти на каждом узле для указателей связного
списка. Кроме того, требуется просматривать список, чтобы искать
указатель на модифицированную копию, которого может и не быть
в списке. Каждая из трех стратегий имеет свои достоинства и недостатки, и все три стратегии применяются на практике в реальных
cc-NUMA-системах.
У данной схемы есть еще одна проблема: как проверять, обновлена
исходная память или нет? Если нужно считать строку кэша, которая не
изменялась, запрос может быть удовлетворен из основной памяти, и при
этом не нужно направлять запрос в кэш. Если же требуется считать измененную строку кэша, запрос должен быть направлен в тот узел, в котором находится эта строка кэша, поскольку только здесь имеется ее
действительная копия. Если же разрешается иметь только одну копию
строки кэша, то контролировать изменения в строках кэша нет никакого
смысла, поскольку любой новый запрос требует передачи сообщения в
кэш, хранящий существующую копию, чтобы объявить ее недействительной. Естественно, для хранения информации о состоянии каждой
строки кэша («чистая» или «грязная») требуются дополнительные биты,
и нужно информировать диспетчер памяти узла-владельца о каждом
изменении строки кэша, даже если существует только одна копия этой
строки. Если же таких копий несколько, то изменение одной из них
означает необходимость объявления всех остальных недействительными, поэтому нужен эффективный протокол, позволяющий избежать ситуации гонок (т. е. возникновения различных копий значения одного и
того же элемента данных). Например, чтобы изменить совместно используемую строку кэша, один из держателей этой строки перед ее изменением должен был бы запросить у узла-владельца монопольный доступ к ней. Такой запрос означал бы объявление всех остальных копий
недействительными.
Подобную технологию обеспечения когерентности кэшей реализует, например, широко распространенный интерфейс SCI (Scalable
Coherent Interface), предназначенный для достижения высоких скоростей доступа к разделяемой памяти с малым временем задержки.
SCI представляет собой комбинацию шины и локальной сети, обеспечивает реализацию когерентности кэш-памяти, размещаемой в узлах,
посредством механизма распределенных каталогов.
45

Существует большое количество различных реализаций архитектуры cc-NUMA: SGI Origin 2000, SGI Origin 3000, Cray ТЗЕ, HP Convex
Exemplar, IBM/Sequent NUMA-Q 2000, HP Superdome… При их создании преследовалась одна цель – построить масштабируемый мультипроцессор высокой производительности с общей памятью. Основные
различия между системами этого класса заключаются в способах поддержания когерентности кэшей в пределах всей вычислительной системы – snooping / snarfing, directory или snooping / snarfing & directory.
Кроме того, различающим признаком является принцип построения и
топология коммуникационной сети, связывающей узлы.
3.2.3. COMA-СИСТЕМЫ
COMA (Cache Only Memory Architecture) – это такая архитектура
системы, в которой локальная память каждого процессора считается
частью большой общей кэш-памяти. Других видов памяти нет. Это
требует перемещения элемента данных (а не копии его значения) тому
процессору, который его затребовал. В COMA отсутствует иерархия
памяти, а адресное пространство является объединением адресных
пространств всех кэшей.
Принципиальная особенность концепции COMA выражается в динамике. Здесь любой элемент данных не привязан статически к какому-либо модулю памяти, хотя и имеет уникальный адрес, остающийся
неизменным в течение всего времени существования переменной.
Просто любое значение вместе с его адресом всегда хранится в единственном кэше. Перенос данных из одной локальной кэш-памяти в
другую не требует участия операционной системы, но предполагает
участие сложной и дорогостоящей аппаратуры управления памятью,
очень похожей (но не в точности совпадающей) с диспетчером памяти
cc-NUMA-систем. Для организации такого режима используют так
называемые справочники (directory), хранящие информацию о текущем расположении всех элементов данных.
Наиболее быстродействующий, но и самый дорогой вариант реализации – размещение в каждом узле полной копии справочника. Каждая
запись такого справочника – это адрес элемента данных и номер узла,
хранящего его значение. Когда процессор обращается к локальному
кэшу для выборки / модификации какого-либо элемента данных, то при
кэш-попадании ни коммуникационная сеть, ни другие узлы не привлекаются. Если же обнаруживается кэш-промах, то диспетчер памяти это-
46

го узла выбирает из своего справочника номер узла – текущего владельца требуемого элемента и через коммуникационную сеть запрашивает
перемещение элемента в свой кэш. В этот момент в каждом узле корректируется запись с адресом этого элемента данных, в нее пишется новый
номер узла-владельца. На каждый кэш-промах требуется затратить не
менее двух циклов работы коммуникационной сети и дополнительно
цикл записи элемента данных с его адресом в кэш нового владельца.
Более дешевый, но и менее быстродействующий вариант – распределение записей справочника по узлам. В этом случае при кэшпромахе диспетчер памяти по старшим разрядам адреса элемента данных определяет, в справочнике какого узла хранится запись с номером
текущего владельца, и по коммуникационной сети отправляет ему запрос. Это узел по хранящейся в нем информации формирует и отправляет текущему владельцу требование на перемещение элемента данных нуждающемуся в нем узлу. В этом варианте на каждый кэшпромах потребуется затратить не менее трех циклов работы коммуникационной сети.
Строка кэша бывшего владельца после перемещения элемента данных в кэш нового владельца становится недействительной. Ясно, что
именно недействительные строки будут использоваться диспетчером
памяти узла для размещения элементов данных, перемещаемых в этот
узел по запросам его процессора. Однако, в принципе, может возникнуть ситуация, при которой в принимающем данные кэше нет ни одной недействительной строки. В ранее рассмотренных системах контроллер кэша обеспечивает вытеснение какой-либо строки кэша в собственный модуль основной памяти. Однако в COMA-системе основной
памяти нет. Логика диспетчера памяти должна обеспечить взаимодействие с одним или несколькими другими узлами (в предельном случае – со всеми) для обнаружения узла, имеющего хотя бы одну недействительную строку и принудительное перемещение вытесняемой
строки в его кэш. На это потребуется заранее неизвестное количество
циклов работы коммуникационной сети.
Еще одна неприятная ситуация возникает, если один и тот же элемент данных требуется попеременно двум или более процессорам.
Этот блок должен перемещаться между узлами туда и обратно при
каждой операции доступа, существенно загружая коммуникационную
сеть. Бороться с такими проблемами в архитектуре COMA можно
только путем правильного распределения вычислительных работ между процессорами, выполняемого программным обеспечением.
47

Архитектура COMA была реализована в целом ряде систем, в частности, в системах с названиями KSR-1 (Kendall Square Research) и
DDM (Data Diffusion Machine), однако существенного развития не получила, как и все NUMA-системы. Основной причиной этого явилась
недостаточно высокая масштабируемость мультипроцессоров с общей
разделяемой памятью при довольно высокой удельной стоимости каждого гигафлопа. Максимальное количество процессоров в таких системах не превышает тысячи. При быстродействии одного процессора
9
10
…1010 операций в секунду это приводит к пределу со значением
примерно 10
12
…1013 операций в секунду.
48

4. ГРАФИЧЕСКИЕ ПРОЦЕССОРЫ
И ВЫЧИСЛИТЕЛЬНЫЕ АКСЕЛЕРАТОРЫ
Графические процессоры и вычислительные акселераторы являются
мощными средствами увеличения производительности компьютеров
(или вычислительных узлов суперкомпьютера), в состав которых они
интегрированы. И те и другие обычно представляют собой вычислительные устройства, созданные на основе одного специального чипа и
реализующие высокопараллельную обработку данных. Принципы, заложенные в основу этой обработки, могут быть различными. Объединение центральных, как правило многоядерных, процессоров с этими
устройствами создает гетерогенную вычислительную систему, показанную на рис. 4.1.
Рис. 4.1. Структура гетерогенной вычислительной системы
49

Основной компьютер системы, показанный на рисунке справа и
названный как Host, управляет несколькими вычислительными устройствами (Compute Device). Каждое такое устройство, в свою очередь, содержит набор относительно независимых друг от друга вычислителей
(Compute Unit), в составе которых работает несколько обрабатывающих
элементов (Processing Element).
4.1. ГРАФИЧЕСКИЕ ПРОЦЕССОРЫ
Эти ускорители вычислений представляют собой развитие и модификацию архитектуры ОКМД (один поток команд, много потоков данных). Основные отличия принципов работы графических процессоров
от базовых идей архитектуры ОКМД состоят в следующем:
вместо принципа «один поток команд» реализуется принцип
«одна программа, исполняемая несколькими ОКМД-подсистемами в
чистом виде, работающими каждая в своем темпе»;
аппаратура графического процессора позволяет организовывать
исполнение огромного по сравнению с обычным многоядерным компьютером количества легковесных потоков управления, обрабатывающих каждый свои собственные данные;
выполняемая графическим процессором программа (обычно
называемая ядром) рассматривается как совокупность блоков потоков,
каждый из которых целиком исполняется одной ОКМД-подсистемой;
блоки потоков и потоки в блоках при запуске ядра могут быть
организованы в одно-, двух- или трехмерные структуры, что позволяет
достаточно просто адаптировать алгоритмы вычислений к природе
решаемой задачи;
кроме общедоступного для всей совокупности потоков блока ос-
новной памяти (обычно называемого глобальной памятью устройства)
каждая ОКМД-подсистема имеет еще несколько уровней памяти с разным быстродействием и разной степенью доступности для исполняемых ею блоков и потоков управления.
Графические процессоры в качестве средств высокопроизводительных вычислений появились как результат развития, совершенствования и конкуренции видеоадаптеров, выпускаемых основными компаниями-производителями – фирмами NVIDIA и AMD (ATI). Вначале
в видеоадаптеры с целью разгрузки центральных процессоров от выполнения рутинных операций переносились простейшие функции обработки графической информации. Сама природа задач компьютерной
графики – однотипная обработка большого количества точек на плоско-
50
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
