
Structured Computer Organization (Архитектура компьютера) / computer_organization_2003
.pdf
Вопросы разработки компьютеров параллельного действия |
573 |
ней, не будет пользоваться особым спросом. В этом разделе мы рассмотрим некоторые вопросы производительности, связанные с созданием архитектур параллельных компьютеров.
Метрика аппаратного обеспечения
В аппаратном обеспечении наибольший интерес представляет скорость работы процессоров, устройств ввода-вывода и сети. Скорость работы процессоров и устройств ввода-вывода такая же, как и в однопроцессорной машине, поэтому ключевыми параметрами в параллельной системе являются те, которые связаны с межсоединением. Здесь есть два ключевых момента: время ожидания и пропускная способность. Мы рассмотрим их по очереди.
Полное время ожидания — это время, которое требуется на то, чтобы процессор отправил пакет и получил ответ. Если пакет посылается в память, то время ожидания — это время, которое требуется на чтение и запись слова или блока слов. Если пакет посылается другому процессору, то время ожидания — это время, которое требуется на межпроцессорную связь для пакетов данного размера. Обычно интерес представляет время ожидания для пакетов минимального размера (как правило, для одного слова или небольшой строки кэш-памяти).
Время ожидания строится из нескольких факторов. Для сетей с коммутацией каналов, сетей с промежуточным хранением и сетей без буферизации пакетов характерно разное время ожидания. Для коммутации каналов время ожидания составляет сумму времени установки и времени передачи. Для установки схемы нужно выслать пробный пакет, чтобы зарезервировать необходимые ресурсы, а затем передать назад сообщение об этом. После этого можно ассемблировать пакет данных. Когда пакет готов, биты можно передавать на полной скорости, поэтому если общее время установки составляет Ts, размер пакета равен р бит, а пропускная способность b битов в секунду, то время ожидания в одну сторону составит Ts+p/b. Если схема дуплексная и никакого времени установки на ответ не требуется, то минимальное время ожидания для передачи пакета размером в р бит и получения ответа размером в р битов составляет Ts+2p/b секунд.
При пакетной коммутации не нужно посылать пробный пакет в пункт назначения заранее, но все равно требуется некоторое время установки, Та, на компоновку пакета. Здесь время передачи в одну сторону составляет Та+р/Ь, но за этот период пакет доходит только до первого коммутатора. При прохождении через сам коммутатор получается некоторая задержка, Т<ъ а затем происходит переход к следующему коммутатору и т. д. Время Td состоит из времени обработки и задержки в очереди (когда нужно ждать, пока не освободится выходной порт). Если имеется п коммутаторов, то общее время ожидания в одну сторону составляет Ta+n(p/b+Td)+p/b, где последнее слагаемое отражает копирование пакета из последнего коммутатора в пункт назначения.
Время ожидания в одну сторону для коммутации без буферизации пакетов и «червоточины» в лучшем случае будет приближаться к Та+р/Ь, поскольку здесь нет пробных пакетов для установки схемы и нет задержки, обусловленной промежуточным хранением. По существу, это время начальной установки для компоновки пакета плюс время на передачу битов. Следовало бы еще прибавить задержку на распространение сигнала, но она обычно незначительна.

5 7 4 Глава 8. Архитектуры компьютеров параллельного действия
Следующая характеристика аппаратного обеспечения — пропускная способность. Многие программы параллельной обработки, особенно в естественных науках, перемещают огромное количество данных, поэтому число байтов, которое система способна перемещать в секунду, имеет очень большое значение для производительности. Существует несколько показателей пропускной способности. Один из них — пропускная способность между двумя секциями — мы уже рассмотрели. Другой показатель — суммарная пропускная способность — вычисляется путем суммирования пропускной способности всех каналов связи. Это число показывает максимальное число битов, которое можно передать сразу. Еще один важный показатель — средняя пропускная способность каждого процессора. Если каждый процессор способен выдавать только 1 Мбайт/с, то от сети с пропускной способностью между секциями в 100 Гбайт/с не будет толку. Скорость взаимодействия будет ограничена тем, сколько данных может выдавать каждый процессор.
На практике приблизиться к теоретически возможной пропускной способности очень трудно. Пропускная способность сокращается по многим причинам. Например, каждый пакет всегда содержит какие-то служебные сигналы и данные: это компоновка, построение заголовка, отправка. При отправке 1024 пакетов по 4 байта каждый мы никогда не достигнем той же пропускной способности, что и при отправке 1 пакета на 4096 байтов. К сожалению, для достижения маленького времени ожидания лучше использовать маленькие пакеты, посколькубольшие надолго блокируют линии и коммутаторы. В результате возникает конфликт между достижением низкого времени ожидания и высокой пропускной способности. Для одних прикладных задач первое важнее, чем второе, для других — наоборот. Важно знать, что всегда можно купить более высокую пропускную способность (добавив больше проводов или поставив более широкие провода), но нельзя купить низкое время ожидания. Поэтомулучше сначаласделать время ожидания как можно меньше, а уже потом заботиться о пропускной способности.
Метрика программного обеспечения
Метрика аппаратного обеспечения показывает, на что способно аппаратное обеспечение. Но пользователей интересует совсем другое. Они хотят знать, насколько быстрее будут работать их программы на компьютере параллельного действия по сравнению с однопроцессорным компьютером. Для них ключевым показателем является коэффициентускорения: насколько быстрее работаетпрограммав п-про- цессорной системе по сравнению с 1-процессорной системой. Результаты обычно иллюстрируются графиком (рис. 8.8.). Здесь мы видим несколько разных параллельных программ, которые работают на мультикомпьютере, состоящем из 64 процессоров Pentium Pro. Каждая кривая показывает повышение скорости работы одной программы с к процессорами как функцию от к. Идеальное повышение скорости показано пунктирной линией, где использование к процессоров заставляет программу работать в к раз быстрее для любого к. Лишь немногие программы достигают совершенного повышения скорости, но естьдостаточное число программ, которые приближаются к идеалу. Скорость работы N-объектной задачи с добавле-


576 Глава 8. Архитектуры компьютеров параллельного действия
Действуют
|
|
|
|
п процессоров |
|
|
|
|
I |
|
Потенциально |
|
|
|
Последовательная |
параллелизируемая |
Действует |
|
|
часть программы |
часть программы |
1 процессор |
|
|
1 |
\ |
|
\ |
|
f |
1-t |
i |
I f |
1-f |
|
|
|
-»-fT-«--—(1 -f )T/n—*- |
|
|
а |
|
|
б |
Рис. 8.9. Программа содержит последовательную часть и параллелизуемую часть (а); результат параллельной обработки части программы (б)
Закон Амдала — это только одна причина, по которой невозможно идеальное повышение скорости. Определенную роль в этом играет и время ожидания в коммуникациях, и ограниченная пропускная способность, и недостатки алгоритмов. Даже если мы имели бы в наличии 1000 процессоров, не все программы можно написать так, чтобы использовать такое большое число процессоров, а непроизводительные издержки для запуска их всех могут быть очень значительными. Кроме того, многие известные алгоритмы трудно подвергнуть параллельной обработке, поэтому в данном случае приходится использовать субоптимальный алгоритм. Для многих прикладных задач желательно заставить программу работать в п раз быстрее, даже если для этого потребуется 2п процессоров. В конце концов, процессоры не такие уж и дорогие.
Как достичь высокой производительности
Самый простой способ — включить в системудополнительные процессоры. Однако добавлять процессоры нужно таким образом, чтобы при этом не ограничивать повышение производительности системы. Система, к которой можно добавлять процессоры и получать соответственно этому большую производительность, называется расширяемой.
Рассмотрим 4 процессора, которыесоединены шиной (рис. 8.10, а). Атеперьпредставим, что мы расширили систему до 16 процессоров, добавив еще 12 (рис. 8.10, б). Если пропускная способность шины составляет b Мбайт/с, то увеличив в 4 раза число процессоров, мы сократим имеющуюся пропускную способность каждого процессора с Ь/4 Мбайт/с до Ь/16 Мбайт/с. Такая система не является расширяемой.
А теперь проделаем то же действие с сеткой (решеткой) межсоединений (рис. 8.10, в, г). В такой топологии при добавлении новых процессоров мы добавляем новые каналы, поэтому при расширении системы суммарная пропускная способность на каждый процессор не снизится, как это было в случае с шиной. Отношение числа каналов к числу процессоров увеличивается от 1,0 при наличии 4 процессоров (4 процессора, 4 канала) до 1,5 при наличии 16 процессоров

Вопросы разработки компьютеров параллельного действия |
|
577 |
(16 процессоров, 24 канала), поэтому с добавлением новых процессоров суммарная пропускная способность на каждый процессор увеличивается.
Процессор
р
?t? ? у ШШ
Шина
а |
6 |
в |
г |
Рис. 8.10. Система из 4 процессоров, соединенных шиной (а); система из 16 процессоров, соединенных шиной (б); сетка межсоединений из 4 процессоров (в); сетка межсоединений из 16 процессоров (г)
Естественно, пропускная способность — это не единственный параметр. Добавление процессоров к шине не увеличивает диаметр сети или время ожидания при отсутствии трафика, а добавление процессоров к решетке, напротив, увеличивает. Диаметр решетки пхп равен 2(п—1), поэтому в худшем случае время ожидания растет примерно как квадратный корень от числа процессоров. Для 400 процессоров диаметр равен 38, а для 1600 процессоров — 78, поэтому если увеличить число процессоров в 4 раза, то диаметр, а следовательно, и среднее время ожидания вырастут приблизительно вдвое.
В идеале расширяемая система при добавлении новых процессоров должна сохранять одну и ту же среднюю пропускную способность на каждый процессор и постоянное среднее время ожидания. На практике сохранение достаточной пропускной способности на каждый процессор осуществимо, но время ожидания растет с увеличением размера. Лучше всего было бы сделать так, чтобы она росла логарифмически, как в гиперкубе.
Дело в том, что время ожидания часто является фатальным для производительности в мелкомодульных и среднемодульных приложениях. Если программе требуются данные, которых нет в ее локальной памяти, на их получение требуется существенное количество времени, и чем больше система, тем больше получается задержка. Эта проблема существует и в мультипроцессорах, и в мультикомпыотерах, поскольку в обоих случаях физическая память разделена на неизменяемые широко раскинувшиеся модули.
Системные разработчики применяют несколько различных технологий, которые позволяют сократить или, по крайней мере, скрыть время ожидания. Первая технология — это копирование данных. Если копии блока данных можно хранить в нескольких местах, то можно увеличить скорость доступа к этим данным. Один из возможных вариантов — использование кэш-памяти, когда одна или несколько копий блоков данных хранятся близко к тому месту, где они могут понадобиться. Другой вариант — сохранять несколько равноправных копий — копий с равным статусом (в противоположность асимметричным отношениям первичности/вторичности, которые наблюдаются при использовании кэш-памяти). Когда сохраняется несколько копий, главные вопросы — это кем, когда и куда они помещены.

5 7 8 Глава 8. Архитектуры компьютеров параллельного действия
Здесь возможны самые разные варианты — от динамического размещения по требованию аппаратного обеспечения до намеренного размещения во время загрузки директив компилятора. Во всех случаях главным вопросом является согласованность управления.
Вторая технология — так называемая упреждающая выборка. Элемент данных можно вызвать еще до того, как он понадобится. Это позволяет перекрыть процесс вызова и процесс выполнения, и когда потребуется этот элемент данных, он уже будет доступен. Упреждающая выборка может быть автоматической, а может контролироваться программой. В кэш-память загружается не только нужное слово, а вся строка кэш-памяти целиком, и другие слова из этой строки тоже могут пригодиться в будущем.
Процессом упреждающей выборки можно управлять и явным образом. Когда компилятор узнает, что ему потребуются какие-либо данные, он может выдать явную команду, чтобы получить эти данные, и выдает он эту команду заранее с таким расчетом, чтобы получить нужные данные вовремя. Такая стратегия требует, чтобы компилятор обладал полными знаниями о машине и ее синхронизации, а также контролировал, куда помещаются все данные. Спекулятивные команды LOAD работают лучше всего, когда абсолютно точно известно, что эти данные потребуются. Ошибка из-за отсутствия страницы при выполнении команды LOAD для ветви, которая в конечном итоге не используется, очень невыгодна.
Третья технология — это многопоточная обработка. В большинстве современных систем поддерживается мультипрограммирование, при котором несколько процессов могут работать одновременно (либо создавать иллюзию параллельной работы на основе разделения времени). Если переключение между процессами можно совершать достаточно быстро, например, предоставляя каждому из них его собственную схему распределения памяти и аппаратные регистры, то когда один процесс блокируется и ожидает прибытия данных, аппаратное обеспечение может быстро переключиться на другой процесс. В предельном случае процессор выполняет первую команду из потока 1, вторую команду из потока 2 и т. д. Таким образом, процессор всегда будет занят, даже при длительном времени ожидания в отдельных потоках.
Некоторые машины автоматически переключаются от процесса к процессу после каждой команды, чтобы скрыть длительное время ожидания. Эта идея была реализована в одном из первых суперкомпьютеров CDC 6600. Было объявлено, что он содержит 10 периферийных процессоров, которые работают параллельно. А на самом деле он содержал только один периферийный процессор, который моделировал 10 процессоров. Он выполнял по порядку по одной команде из каждого процессора, сначала одну команду из процессора 1, затем одну команду из процессора 2 и т. д.
Четвертая технология — использование неблокирующих записей. Обычно при выполнении команды STORE, процессор ждет, пока она не закончится, и только после этого продолжает работу. При наличии неблокирующих записей начинается операция памяти, но программа все равно продолжает работу. Продолжать работу программы при выполнении команды LOAD сложнее, но даже это возможно, если применять исполнение с изменением последовательности.

Вопросы разработки компьютеров параллельного действия |
579 |
Программное обеспечение
Эта глава в первую очередь посвящена архитектуре параллельных компьютеров, но все же стоит сказать несколько слов о программном обеспечении. Без программного обеспечения с параллельной обработкой параллельное аппаратное обеспечение не принесет никакой пользы, поэтому хорошие разработчики аппаратного обеспечения должны учитывать особенности программного обеспечения. Подробнее о программном обеспечении для параллельных компьютеров см. [160].
Существует 4 подхода к разработке программного обеспечения для параллельных компьютеров. Первый подход — добавление специальных библиотек численного анализа к обычным последовательным языкам. Например, библиотечная процедура для инвертирования большой матрицы или для решения ряда дифференциальных уравнений с частными производными может быть вызвана из последовательной программы, после чего она будет выполняться на параллельном процессоре, а программист даже не будет знать о существовании параллелизма. Недостаток этого подхода состоит в том, что параллелизм может применяться только в нескольких процедурах, а основная часть программы останется последовательной.
Второй подход — добавление специальных библиотек, содержащих примитивы коммуникации и управления. Здесь программист сам создает процесс параллелизма и управляет им, используя дополнительные примитивы.
^_ Следующий шаг — добавление нескольких специальных конструкций к существующим языкам программирования, позволяющих, например, легко порождать новые параллельные процессы, выполнять повторения цикла параллельно или выполнять арифметические действия над всеми элементами вектора одновременно. Этот подход широко используется, и очень во многие языки программирования были включены элементы параллелизма.
Четвертый подход — ввести совершенно новый язык специально для параллельной обработки. Очевидное преимущество такого языка — он очень хорошо подходит для параллельного программирования, но недостаток его в том, что программисты должны изучать новый язык. Большинство новых параллельных языков императивные (их команды изменяют переменные состояния), но некоторые из них функциональные, логические или объектно-ориентированные.
Существует очень много библиотек, расширений языков и новых языков, изобретенных специально для параллельного программирования, и они дают широчайший спектр возможностей, поэтому их очень трудно классифицировать. Мы сосредоточим наше внимание на пяти ключевых вопросах, которые формируют основу программного обеспечения для компьютеров параллельного действия:
1.Модели управления.
2.Степень распараллеливания процессов.
3.Вычислительные парадигмы.
4.Методы коммуникации.
5.Базисные элементы синхронизации.
Ниже мы обсудим каждый из этих вопросов в отдельности.

5 8 0 Глава 8. Архитектуры компьютеров параллельного действия
Модели управления
Самый фундаментальный вопрос в работе программного обеспечения — сколько будет потоков управления, один или несколько. В первой модели существует одна программа и один счетчик команд, но несколько наборов данных. Каждая команда выполняется над всеми наборами данных одновременно разными обрабатывающими элементами.
В качестве примера рассмотрим программу, которая получает ежечасные измерения температур от тысяч датчиков и должна вычислить среднюю температуру для каждого датчика. Когда программа вызывает команду
LOAD THE TEMPERATURE FOR 1 A.M. INTO REGISTER Rl
(загрузить температуру в 1 час ночи в регистр R1), каждый процессор выполняет эту команду, используя свои собственные данные и свой регистр R1. Затем, когда программа вызывает команду
ADD THE TEMPERATURE FOR 2 A.M. TO REGISTER Rl
(добавить температуру в 2 часа ночи в регистр R1), каждый процессор выполняет эту команду, используя свои собственные данные. В конце вычислений каждый процессор должен будет сосчитать среднюю температуру для каждого отдельного датчика.
Такая модель программирования имеет очень большое значение для аппаратного обеспечения. По существу, это значит, что каждый обрабатывающий элемент — это АЛУ и память, без схемы декодирования команд. Вместо этого один центральный блок вызывает команды и сообщает всем АЛУ, что делать дальше.
Альтернативная модель предполагает несколько потоков управления, каждый из которых содержит собственный счетчик команд, регистры и локальные переменные. Каждый поток управления выполняет свою собственную программу над своими данными, при этом он время от времени может взаимодействовать с другими потоками управления. Существует множество вариаций этой идеи, и в совокупности они формируют основную модель для параллельной обработки. По этой причине мы сосредоточимся на параллельной обработке с несколькими потоками контроля.
Степень распараллеливания процессов
Параллелизм управления можно вводить на разных уровнях. На самом низком уровне элементы параллелизма могут содержаться в отдельных машинных командах (например, в архитектуре IA-64). Программисты обычно не знают о существовании такого параллелизма — он управляется компилятором или аппаратным обеспечением.
На более высоком уровне мы приходим к параллелизму на уровне блоков (block-level parallelism), который позволяет программистам самим контролировать, какие высказывания будут выполняться последовательно, а какие — параллельно. Например, в языке Algol-68 выражение
begin Statement-1; Statement-2: Statement-3 end
использовалось для создания блока трех (в данном случае трех) произвольных высказываний, которые должны выполняться последовательно, а выражение
begin Statement-1. Statement-2. Statement-3 end

Вопросы разработки компьютеров параллельного действия |
|
581 |
использовалось для параллельного выполнения тех же трех высказываний. С помощью правильного размещения точек с запятой, запятых, скобок и разграничителей begin/end можно было записать произвольную комбинацию команд для последовательного или параллельного выполнения.
Присутствует параллелизм на уровне более крупных структурных единиц, когда можно вызвать процедуру и не заставлять вызывающую программу ждать завершения этой процедуры. Это значит, что вызывающая программа и вызванная процедура будут работать параллельно. Если вызывающая программа находится
вцикле, который вызывает процедуру при каждом прохождении и не ждет завершения этих процедур, то значит, большое число параллельных процедур запускается одновременно.
Другая форма параллелизма — создание или порождение для каждого процесса нескольких потоков, каждый из которых работает в пределах адресного пространства этого процесса. Каждый поток имеет свой счетчик команд, свои регистры и стек, но разделяет все остальное адресное пространство (а также все глобальные переменные) со всеми другими потоками. (В отличие от потоков разные процессы не разделяют общего адресного пространства.) Потоки работают независимо друг от друга, иногда на разных процессорах. В одних системах операционная система располагает информацией обо всех потоках и осуществляет планирование потоков;
вдругих системах каждый пользовательский процесс сам выполняет планирование потоков и управляет потоками, а операционной системе об этом неизвестно.
Наконец, параллелизм на уровне еще более крупных структурных единиц — несколько независимых процессов, которые вместе работают над решением одной задачи. В отличие от потоков независимые процессы не разделяют общее адресное пространство, поэтому задача должна быть разделена на довольно большие куски, по одному на каждый процесс.
Вычислительные парадигмы
В большинстве параллельных программ, особенно в тех, которые содержат большое число потоков или независимых процессов, используется некоторая парадигма для структуризации их работы. Существует множество таких парадигм. В этом разделе мы упомянем только несколько самых популярных.
Первая парадигма — SPMD (Single Program Multiple Data — одна программа, несколько потоков данных). Хотя система состоит из нескольких независимых процессов, они все выполняют одну и ту же программу, но над разными наборами данных. Только сейчас, в отличие от примера с температурой, все процессы выполняют одни и те же вычисления, но каждый в своем пространстве.
Вторая парадигма — конвейер с тремя процессами (рис. 8.11, а). Данные поступают в первый процесс, который трансформирует их и передает второму процессу для чтения и т. д. Если поток данных длинный (например, если это видеоизображение), все процессоры могут быть заняты одновременно. Так работают конвейеры в системе UNIX. Они могут работать как отдельные процессы параллельно в мультикомпьютере или мультипроцессоре.
Следующая парадигма — фазированное вычисление (рис. 8.11, б), когда работа разделяется на фазы, например, повторения цикла. Во время каждой фазы несколько процессов работают параллельно, но если один из процессов закончит

5 8 2 Глава8.Архитектурыкомпьютеровпараллельногодействия
свою работу, он должен ждать до тех пор, пока все остальные процессы не завершат свою работу, и только после этого начинается следующая фаза. Четвертая парадигма — «разделяйивластвуй»,изображеннаянарис. 8.11, б,вкоторойодинпроцесс запускается, а затем порождает другие процессы, которым он может передать часть работы. Можно провести аналогию с генеральным подрядчиком, который получает приказ, затем поручает значительную часть работы каменщикам, электрикам, водопроводчикам, малярам и другим подчиненным. Каждый из них, в свою очередь, может поручить часть своей работы другим рабочим.
1\ |
|
|
|
|
Pi |
|
Рабочаяочередь |
||
Pi |
P2 |
Рз |
|
|
|
||||
/ |
\ |
|
|
|
|
||||
Pi |
|
|
> |
p2 |
|
Рз |
|
1 |
\ |
|
|
|
|
|
|||||
1 |
Момент синхронизации |
|
|
|
Pi |
р2 |
Рз |
||
|
|
|
|
|
|
|
|
|
|
pг |
|
|
p4 |
|
p5 |
P- |
|
|
|
|
|
|
/ |
|
|
|
|||
|
Pi |
P2 |
Рз |
|
|
|
|
||
|
|
|
|
p7 |
|
P8 |
Процесс |
|
|
p |
|
|
|
|
|
|
|
||
Момент синхронизации |
Ч |
|
У |
|
|
|
|||
|
|
|
|
|
|||||
\\ |
\\ |
1\ |
1\ |
|
p9 |
|
|
|
|
Рис. 8.11. Вычислительные парадигмы: конвейер(а); фазированное вычисление(б); «разделяйивластвуй»(в);replicatedworker(г)
Последний пример — парадигма replicated worker (см. рис. 8.11, г). Здесь существует центральная очередь, и рабочие процессы получают задачи из этой очереди и выполняют их. Если задача порождает новые задачи, они добавляются к центральной очереди. Каждый раз, когда рабочий процесс завершает выполнение текущей задачи, он получает из очереди следующую задачу.
Методы коммуникации
Если программа разделена на части, скажем, на процессы, которые работают параллельно, эти части (процессы) должны каким-то образом взаимодействовать друг с другом. Такое взаимодействие можно осуществить одним из двух способов:
спомощью общих переменных и с помощью передачи сообщений. В первом случае все процессы имеют доступ к общей логической памяти и взаимодействуют, считывая и записывая информацию в эту память. Например, один процесс может установить переменную, а другой процесс может прочитать ее.
Вмультипроцессоре переменные могут разделяться между несколькими процессами с помощью отображения одной и той же страницы в адресное пространство каждого процесса. Затем общие переменные можно считывать и записывать
спомощью обычных машинных команд LOAD и STORE. Даже в мультикомпьютере