Автор работы: Пользователь скрыл имя, 26 Марта 2012 в 23:27, лекция
Технологии высокопроизводительных вычислений сегодня переживают весьма резкие качественные изменения. Круг вопросов, подлежащих обсуждению при систематическом изложении предмета, не устоялся и стремительно меняется. По этой причине мы разделим настоящий текст на две части.
В первой части, озаглавленной «Освоенные технологии», изложим предмет так, как его надо было рассказывать, скажем, 2 – 3 года назад, не забывая, конечно, о линейном, количественном развитии, имевшем место за эти 2 – 3 года в рамках традиционных подходов.
Введение.
Часть 1. Освоенные технологии.
1. Таксономия суперкомпьютеров и применяемых в связи с ними программистских технологий.
1.1. Архитектура фон Неймана.
1.2. Три этапа развития суперкомпьютерных технологий и две суперкомпьютерных революции.
1.3. Способы объединения многих процессоров в единую систему.
1.4. Альтернативные архитектуры.
1.5. Простейшая модельная программа.
1.5.1. Решение двумерной краевой задачи для уравнения теплопроводности методом Якоби.
1.5.2. Параллельная реализация «на бумаге».
1.5.3. Что потребуется для параллельной реализации на практике.
1.6. Общий состав программного обеспечения вычислительного кластера
1.7. Некоторые основные определения.
1.8. Технологии параллельной обработки данных без использования суперкомпьютеров.
2. Некоторые основные понятия архитектуры процессоров и ОС.
2.1. Некоторые основные определения.
2.2. Пример системы команд: обработка данных в памяти.
2.3. Чего нам не хватает.
2.3.1. Общее представление об управлении внешними устройствами.
2.3.2. Программа – диспетчер.
2.3.3. Прерывания.
2.3.4. Защита памяти и многорежимность процессора.
2.3.5. Виртуальная память.
2.4. Еще несколько определений.
3. Критерии эффективности коммуникационной сети.
4. Обзор процессорных и сетевых решений, применяемых в современных кластерах.
4.1. Выбор процессора.
4.2. Выбор коммуникационной сети.
5. Суперкомпьютер МВС-1000 и метакластер МВС-900.
5.1. Основные принципы организации МВС – 1000.
5.2. Как работает и зачем нужен метакластер МВС – 900.
6. Модели и технологии параллельного программирования.
6.1. Два способа параллельной обработки данных.
6.2. Два лица программистской модели.
6.3. Модель: явный двусторонний обмен сообщениями.
6.4. Модель: односторонний обмен сообщениями.
6.5. Модель: NUMA.
6.6. Модели, производные от явного двустороннего обмена сообщениями.
6.6.1. Модель библиотек коллективных операций над распределенными массивами.
6.6.2. Модель параллельных трансляторов в стиле HPF.
6.6.3. Модель непроцедурных языков.
6.7. Парадокс неприятия новых технологий.
6.8. Немного о технике реализации MPI.
Часть 2. Технологии, появляющиеся сегодня.
7. Почему «эпоха кластеров» заканчивается.
Литература.
2.2. Пример системы команд: обработка данных в памяти.
Рассмотрим подмножество системы команд М-20 (она же БЭСМ-3 и БЭСМ-4) – вычислительной машины, выпускавшейся в СССР в 60-х годах прошлого столетия [4]. Помимо прочего, архитектура этой машины отличается исключительной простотой, что для нас сейчас крайне полезно.
В этом разделе сосредоточимся на командах, выполняющих обработку данных как таковую. Оставим пока в стороне вопрос о том, как команды и данные попадают в память, а результаты вычислений из нее выводятся.
Оперативная память состоит из слов, занумерованных от 0 подряд. В слове 45 разрядов, занумерованных справа от 1. Из слова номер 0 всегда читается двоичный 0.
Слово может хранить число или команду.
Формат числа:
П З ЕЕЕЕЕЕЕ М………….М
45 44 43 37 36 1 (номера разрядов).
М – мантисса.
Е – код порядка, (64+порядок)
З – знак числа (0-плюс),
П – признак (арифметического смысла не имеет, при арифметических операциях наследуется).
Число имеет значение: 0.М*2**(Е-64), со знаком З.
Видим, что речь идет о числах с плавающей точкой.
Формат команды:
ППП КККККК А1….А1 А2….А2 А3….А3
45 43 42 37 36 25 24 13 12 1 (номера разрядов).
ППП – трехбитный код признаков,
КККККК – шестибитный код операции,
А1, А2, А3 – двенадцатибитные адреса операндов. Обычно первые два адреса указывают исходные данные, третий – результат. Например, в команде сложения содержимое слова с адресом А1 складывается с содержимым слова с адресом А2, а результат помещается по адресу А3. При этом к адресу, указанному в соответствующем поле команды, прибавляется значение индекс – регистра, если соответствующий этому адресу бит кода признаков равен 1.
Архитектурно в процессор входят:
- счетчик команд,
- триггер «омега»,
- индекс-регистр.
Счетчик команд всегда равен адресу следующей команды. Если текущая выполняемая команда – не команда перехода, то при выполнении команды он автоматически увеличивается на единицу, то есть следующая команда берется из следующего слова памяти.
Триггер «омега» - дополнительный признак результата выполнения операции, например, признак того, что при выполнении сложения получилось отрицательное число.
Вопросы на понимание:
- сколько слов оперативной памяти может быть в этой машине?
- сколько команд может быть в этом процессоре?
- какова разрядность счетчика команд?
- можно ли выполнить число?
- можно ли прибавить единицу к команде?
Ширина полей команды кратна трем разрядам, поэтому будем использовать при записи значений этих полей восьмеричную систему счисления (восьмеричная цифра – это как раз 3 разряда).
Основные команды (в восьмеричном виде):
01 – сложение,
02 – вычитание,
03 – вычитание модулей,
04 – деление,
05 – умножение,
44 – квадратный корень.
Некоторые команды, помимо вычисления результата, изменяют значение триггера «омега». Например, при выполнении команд группы сложения (сложение, вычитание) триггер «омега» становится равным 1, если результат не отрицателен, иначе – равным 0.
У команд группы умножения омега=1, если порядок положителен.
06 – сложение порядка с адресом,
46 – вычитание порядка из адреса,
13 – сложение адресных частей команд,
33 – вычитание адресных частей команд,
омега=1, если переполнение или заем.
Эти команды предназначены для вычисления команд, которые сами же потом будут выполняться. Система команд этой машины столь аскетична, что для организации, например, сложных циклов или косвенной адресации приходилось писать программы, модифицирующие (вычисляющие) собственный код. С развитием в современных процессорах режимов адресации писать программы таким образом стало не принято, по крайней мере, в кругу приличных людей, но на описываемой машине поступать именно так приходилось не только разработчикам вирусов.
00 – пересылка,
56 – безусловный переход с пересылкой,
16 – переход с возвратом.
76 – переход по омега==0
36 – переход по омега==1
77 – стоп
52 – засылка адреса в индекс,
72 – засылка кода в индекс.
Из всего сказанного здесь принципиально важно то, что процессор оснащен некоторым набором арифметических и логических операций, а также командами условного перехода, то есть возможностью выбрать дальнейший путь выполнения программы в зависимости от промежуточных результатов вычислений.
Пока мы можем сделать два важных вывода:
1). Алгоритмически приведенных скромных возможностей достаточно для реализации любой вычислительной процедуры, которая может быть записана, например, на С или Фортране,
2). Технологически мы еще очень далеки от понимания того, как работает, например, ОС Windows. Мы совсем не представляем себе, как программа попадает в память и получает управление, как организуется параллельное выполнение нескольких программ на одном процессоре, как управляются внешние устройства, и т. п.
Для начала все же приведем пример программы, вычисляющей абсолютную величину значения A*x + B*y.
Для начала требуется распределить память. Договоримся, что:
A имеет адрес 100,
B имеет адрес 101,
X имеет адрес 102,
Y имеет адрес 103,
Результат необходимо поместить по адресу 104,
В качестве рабочих ячеек будем использовать слова со 105 по 107,
Сама программа будут располагаться в памяти по адресу 110.
Теперь можно писать программу:
110: 0 05 0100 0102 0105 A*x => 105
111: 0 05 0101 0103 0106 B*y => 106
112: 0 01 0105 0106 0104 105+106 => 105
113: 0 36 0000 0115 0000 если «омега»==1, идти на конец
114: 0 02 0000 0104 0104 0-104 => 104 (из 0-й ячейки читается 0)
115: 0 77 0000 0000 0000 стоп
Как это все работало:
На пульте набирали адрес ввода, клали колоду перфокарт под утюг, и нажимали кнопку «ввод». Потом на пульте набирали адрес первой команды, и нажимали кнопку «пуск». И ждали команды «77». Конечно, программное управление внешними устройствами было предусмотрено (мы это здесь опустили).
2.3. Чего нам не хватает.
Видим, что работать так крайне трудно. Из совершенно очевидных шагов по преодолению этих трудностей мы сейчас выведем основные понятия архитектуры операционных систем, которые остались в принципе неизменными с тех самых пор. Каковы же трудности?
1). Очень трудно программировать. Попробуйте написать a*x**2+b*y**2+c*z**2. И основная трудность даже не в том, что надо выписывать коды операций – к этому привыкаешь. Трудность в том, что надо указывать адреса, а они «плывут» при малейших изменениях в программе. Когда был написан ассемблер, вычисляющий адреса сам, стало много легче. Потом появились трансляторы алгоритмических языков.
Одновременно эволюционировали системы команд. Одно из важнейших направлений эволюции: избавиться от необходимости модифицировать программу по мере ее работы.
Все системы команд процессоров общего назначения избыточны и алгоритмически эквивалентны, то есть не может быть вычислительной процедуры, выразимой в системе команд одного процессора и в принципе не выразимой в системе команд другого.
2). Невероятно трудно запускать программу. Мы привыкли непринужденно оперировать множеством окошек на экране, которые все открыты и все активны. А как это получается? Это получается, «потому что операционная система». А у нее – то это как получается?
3). Совершенно не понятно, как организован ввод-вывод. Это объяснить проще всего, так что с этого и начнем.
2.3.1. Общее представление об управлении внешними устройствами.
С точки зрения программы, любое внешнее устройство – это набор регистров, обладающих, помимо способности хранить и/или выдавать записанные в них данные, некоторыми специальными свойствами. Рассмотрим такое простейшее внешнее устройство, как Com-порт. Предположим для конкретности, что извне к нему подключен алфавитно-цифровой терминал.
Com-порт состоит из двух каналов: вывода и ввода. Каждый из каналов управляется двумя регистрами: регистром данных и регистром состояния.
Регистр данных имеет ширину, например, 8 бит, простейший регистр состояния состоит из одного бита.
Рассмотрим работу канала вывода.
В начальный момент регистр состояния содержит «1», что означает «линия вывода свободна». При записи в регистр данных некоторого числа единица в регистре состояния гаснет (линия вывода занята передачей), а само число передается по линии вывода на терминал. Если это число – код буквы «А», на терминале в текущей позиции курсора появится буква «А». Это будет означать, что вывод символа из регистра данных завершен, и в регистре состояния снова появится «1» - линия свободна для вывода следующего символа.
Канал ввода работает аналогично, но «зеркально»: появление «1» в регистре состояния означает, что линия положила в регистр данных некоторое значение (код клавиши, нажатой на клавиатуре терминала), которое программа теперь должна забрать. При чтении программой регистра данных ввода единица в регистре состояния погаснет, и снова появится там лишь при поступлении с клавиатуры очередного символа.
Осталось наполнить конкретным содержанием понятия «запись в регистр» и «чтение из регистра». Очевидно, это какие-то команды процессора, аналогов которым мы в нашем беглом обзоре системы команд не видели. В разных системах команд эта проблема решается одним из всего двух способов (иногда – обоими):
Первый способ: регистры внешних устройств (обычно их называют портами, чтобы не путать с регистрами общего назначения в составе процессора) занумерованы, и для обмена данными между ними и процессором предусмотрены специальные команды. В нашем примере процессора, в составе которого регистров общего назначения нет вообще, а есть только память и порты, это могли бы быть, например, команды: «записать содержимое слова по адресу А1 в порт, номер которого – А3», и, соответственно, «прочитать содержимое порта номер А1 в слово по адресу А3».
Второй способ: часть адресов памяти не используется для адресации именно памяти, а используется для доступа к портам внешних устройств. Порты просто «маскируются» под слова памяти, что позволяет работать с ними обычными процессорными командами. Например, если в команде сложения указать в качестве адресов слагаемых адреса слов памяти, содержащих, соответственно, код буквы «А» и единицу, а в качестве адреса результата – адрес «слова памяти», которое на самом деле – регистр данных терминальной линии вывода, на терминале появится буква «В».
В процессоре “Pentium”, например, применяются оба способа, а в выпускавшихся еще недавно процессорах “Alpha” – только второй.
Более сложные внешние устройства, такие, как сетевые адаптеры или контроллеры дисков, включают в себя большее количество портов с более сложной логикой их обслуживания, но в принципе практически не отличаются от разобранного только что тривиального примера.
Замечание о видах памяти в многопроцессорных вычислительных системах.
Теперь наше представление об алгоритмике системы команд процессора стало более или менее замкнутым – мы можем представить себе, как именно (в принципе, конечно, а не в деталях) превращается в процессорные команды и затем выполняется любая программа, включающая в себя не только внутреннюю переработку данных, но и ввод-вывод. Вернемся немного назад и посмотрим, как выглядят с этой точки зрения наши рассуждения из п. 1.3 «Способы объединения многих процессоров в единую систему». Говоря, что процессору доступна некоторая память, мы имеем в виду, что существуют такие значения адресов, использование которых в качестве адресных полей в процессорных командах приведет к адресации слов именно этой памяти. Как выглядит в этом смысле, например, MPP – система? Общей памяти в ней нет. Построим мысленно кластер из двух узлов, соединив их Com-порты нуль-модемным кабелем. Легко видеть, что в этой системе способы доступа к «своей» и «чужой» памяти, действительно, радикально отличаются. Для доступа к «своей» ячейке достаточно использовать ее номер в качестве адреса в любой процессорной команде. Для доступа к «чужой» надо, во-первых, чтобы процессор, находящийся по другую сторону линии связи, выдал содержимое этой ячейки в линию, «просовывая» его, байт за байтом, через регистр данных линии вывода, и не забывая правильно реагировать на значение регистра состояния вывода. Во-вторых, нам надо «подобрать» это значение на своей стороне линии, «вынув» его, байт за байтом, из регистра данных ввода, по мере появления единиц в регистре состояния ввода. Следовательно, в отличие от обращения к своей памяти, требуются согласованные действия на двух сторонах, и действия эти – сложные и длительные, сводящиеся к выполнению особых, часто – очень длинных, последовательностей команд, предназначенных исключительно для управления коммуникационным оборудованием.
Информация о работе Технологии высокопроизводительных вычислений