Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Методы Монте-Карло для параллельных вычислений. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
☆
устройств, а S > 0 и P > 0, S + P = 1 — доли последовательной и па­раллельной частей программы по отношению к общему времени выпол­нения программы одним процессом. Для метода Монте-Карло может оказаться верным соотношение S P. Тогда, по известному второму закону Амдала [2], максимальное ускорение
R =
1
S + P/K
приблизится к предельному значению K — числу процессоров.
Хотя имеется обширная журнальная и монографическая лите­ратура, посвященная теоретическим основам и приложениям методов Монте-Карло, практически нет учебников и научных монографий, из­лагающих различные возможности применения параллельных вычисле­ний к статистическим испытаниям, а информация рассеяна по публика­циям в научных журналах и трудах конференций. Предлагаемая книга собирает разрозненный материал и может служить вспомогательным источником для студентов и заинтересованных лиц, встречающихся с применением методов статистических испытаний в своей деятельности. Материал книги может быть использован в общих и специальных кур­сах по методам вычислений и методам параллельного программиро­вания. У читателя предполагается знание математического анализа и основных понятий теории вероятностей, алгоритмических языков про­граммирования высокого уровня (в книге для примеров используется язык программирования С++) в объеме бакалавриата по математиче­ским и физическим специальностям в ВУЗе.
Часть раздела 6.1, касающаяся кибернетического подхода, и раз­дел 6.2 отражают результаты исследований авторов. Приведенные при­меры программ также написаны авторами. Раздел 7 книги предостав­лен В.П. Гергелем и А.В. Горшковым. Большая часть книги написана на основе литературы, указанной в списке литературы в конце книги. При этом все неточности изложения, разумеется, лежат на совести авторов.
Авторы выражают признательность декану факультета вычис­лительной математики и кибернетики Нижегородского государствен­ного университета им. Н.И. Лобачевского профессору В.П. Гергелю за предложение написать эту книгу, равно как за внимание, поддержку и конструктивные замечания в процессе работы. Авторы также считают необходимым выразить благодарность рецензентам, чей труд позволил существенно улучшить окончательный текст.
11
Часть I
О 
 
Глава 1. Модели и системы параллельных
Процессор
Память
Данные
вычислений
1.1. Параллельные вычисления с общей памятью
Для выполнения последовательных программ достаточно ком­пьютера, схематически изображенного на рис. 1.1. Такой компьютер имеет центральный процессор и оперативную память, к которой про­цессор обращается для выбора очередной команды и данных для обра­ботки. Память здесь может пониматься в достаточно широком смысле и включать как оперативную, так и внешнюю память. Процессор прин­ципиально последовательный: в каждый момент времени он может вы­полнять команды только из одной программы (задачи, потока команд). На аппаратном уровне такой процессор может включать механизм пере­ключения между программами. Каждой из присутствующих в компью­тере программ выделяется некоторый квант процессорного времени, и процессор в определенном порядке предоставляет свои ресурсы про­грамме за программой. Со стороны пользователя возникает иллюзия параллельной работы многих программ. Ответственность за переклю­чение между программами и сохранность их рабочих данных ложится на операционную систему.
например, текстовый редактор и проигрыватель видео. Запущенные вместе эти программы практически не должны взаимодействовать друг
Рис. 1.1. Схема компьютера для последовательных вычислений
Рассмотрим две программы, выполняющие различные функции,
13
с другом и основной функцией операционной системы будет разграни­чение памяти для обеих программ. В этом случае каждая программа будет реализована в виде отдельного процесса. Каждый процесс, таким образом, характеризуется своей областью памяти (под команды и дан­ные), возможностями доступа к устройствам ввода-вывода и прочим си­стемным ресурсам, в том числе и к функциям операционной системы. Как правило, порождение нового процесса операционной системой — достаточно времязатратная операция, а взаимодействие процессов осу­ществляется через специальные процедуры передачи данных. Создание разделяемых участков памяти, видимых несколькими процессами, так­же возможно, но должно тщательно планироваться программистом и требует вызова специальных функций операционной системы.
В то же время, работа текстового редактора может заключаться в одновременной обработке нового вводимого пользователем текста и в проверке орфографии с грамматикой. Обе задачи должны выполняться в рамках одной программы, видеть один и тот же рабочий материал, активно взаимодействовать друг с другом — оперативно реагировать на ввод и редактирование пользователя, начинать грамматический раз­бор сначала при добавлении или удалении слов и знаков препинания. При открытии файла с диска можно проверять орфографию одновре­менно на разных страницах. Более того, некоторые функции должны легко приостанавливаться и возобновлять выполнение. В этом случае используют второе средство организации параллельной работы — пото- ки. Один процесс может порождать потоки, которые будут исполняться параллельно друг с другом (то есть в режиме разделения времени про­цессора). Все потоки, имеющие общего родителя, разделяют общую па­мять (область данных), но каждый поток имеет свой собственный стек. Как правило, поток создается для выполнения конкретной функции. Однако эта функция может вызывать другие функции.
Чтобы обеспечить действительно одновременное исполнение ко­манд из разных процессов и потоков, были разработаны многопроцес- сорные компьютеры с общей памятью (рис. 1.2). В настоящее время появились также доступные многоядерные процессоры, реализующие в принципе ту же архитектуру. Теперь за один квант времени могут исполняться команды стольких процессов (потоков), сколько имеется физических процессоров (ядер).
Рассмотрим задачу о вычислении суммы
zi= xi+ yi, i = 1, 2, . . . , n (1.1)
14
Процессор
Данные
Процессор
Данные
Процессор
Данные
Память
Рис. 1.2. Схема многопроцессорного компьютера с общей памятью
Основной поток
z[i] = x[i] + y[i];
for(int i=0; i<n; i++)
двух векторов x = (x1, x2, . . . , xn) и y = (y1, y2, . . . , yn) одина­кового размера n. На примере этой задачи познакомимся с типовыми решениями, предлагаемыми активно применяемой в настоящее время технологией OpenMP. Разобьем массив на две половины и передадим суммирование в каждой половине своему потоку, как изображено на рис. 1.4. Поскольку основной поток не может использовать содержимое вектора z до момента окончания работы вспомогательного потока, то выполнение основного потока должно быть временно приостановлено, если вычисление подвектора (z1, z2, . . . , z чем вычисление вектора (z
Рис. 1.3. Решение задачи о сложении двух векторов последовательным алго­ритмом. Стрелками указан ход вычислительного процесса
[n/2]+1
, z
[n/2]+2
) закончилось раньше,
[n/2]
, . . . , zn).
Библиотека OpenMP берет на себя написание функций потоков и создание потоков во время выполнения программы, а на программиста ложится обязанность специальной разметки исходной последовательной программы с помощью директив препроцессора. Следующая програм-
15
ма 1.1 демонстрирует рассматриваемое решение с помощью OpenMP.
Основной поток
Синхронизирующий барьер
Вспомогательный поток
z[i] = x[i] + y[i];
for(int i=0; i<n/2; i++)
z[i] = x[i] + y[i];
for(int i=n/2; i<n; i++)
Рис. 1.4. Решение задачи о сложении двух векторов параллельным алгоритмом. Стрелками указан ход вычислительного процесса
Программа 1.1. Сложение двух векторов, библиотека OpenMP
1 # inc l u d e <omp . h >
2 3 # defin e N 100 4 i n t ma i n ( i nt , c h a r * * ) 5 { 6 doubl e x [N ] , y [ N ] , z [ N ];
7 8 // Ин ици а л иза ц и я ма с с и в о в x , y ...
9
10 // По м ечае м уч а с т о к , в к о т о р ом с озд а ю т с я 11 // и вы п олн я ю т ся па р алл е л ь ные по т оки 12 # pragm a om p se c tion s 13 {
14 15 # pragm a om p se c tion 16 { 17 for ( int i = 0 ; i <N / 2 ; i++) 18 z[ i ] = x [ i] + y[ i ]; 19 }
20 21 # pragm a om p se c tion 22 { 23 for ( int i= N /2; i < N ; i + + ) 24 z[ i ] = x [ i] + y[ i ]; 25 }
16
26 27 } 28 // Пр одо л ж а е м в ычи с л е ния в ос н о вном по т о ке ... 29 }
Как видно, вместо создания специальной функции и упаковки–распа­ковки аргументов этой функции группа команд для исполнения в одном потоке выделяется в специальную секцию (section). В данном при­мере легко увидеть, что разбиение на два подвектора вручную доста­точно искусственно и не является наилучшим решением, если имеется больше двух процессоров (ядер). Более того, обе параллельные секции в строках 17–18 и строках 23–24 выполняют одну последовательность действий, но над разными данными. Поэтому предусмотрено еще од­но мощное средство распараллеливания цикла. Вместо строк 12–27 в программе 1.1 достаточно написать:
1 # pragm a om p for 2 fo r ( in t i=0; i < N ; i ++) 3 z[ i ] = x [ i] + y[ i ];
При этом работа будет распределена по всем имеющимся процессорам (ядрам), а вмешательство программиста по модификации исходного текста последовательной программы окажется минимальным.
Поскольку все потоки имеют доступ к одним и тем же участ­кам памяти в области данных и в куче, следует принимать специаль­ные меры для поддержания правильного состояния памяти. Рассмот­рим в качестве примера задачу о вычислении скалярного произведе­ния двух векторов. Пусть даны векторы x = (x1, x2, . . . , xn) и y =
= (y1, y2, . . . , yn). Требуется вычислить величину
r = x1y1+ x2y2+ .. . + xnyn. (1.2)
Используя два потока, можно вычислить сначала частичные суммы
r2= x
r1= x1y1+ x2y2+ .. . + x
[n/2]+1y[n/2]+1
+ x
[n/2]+2y[n/2]+2
[n/2]y[n/2]
,
+ .. . + xnyn,
а затем найти r = r1+ r2. При этом основной поток должен дождаться завершения работы вспомогательного потока, получить от него значе­ние r2и затем присвоить переменной r значение r1+ r2. Такое решение применяется в библиотеке OpenMP, как показано в следующем приме­ре:
17
1 # pragm a om p for re d ucti o n ( + : r ) 2 fo r ( in t i=0; i < N ; i ++) 3 r += x[ i ]* y [i ] ;
Здесь ключевое слово reduction указывает, что результат работы цик­ла накапливается в переменной r с помощью операции сложения. Пе­ременные r1, r2— копии r внутри потоков — будут созданы неявно компилятором.
Полное и систематическое описание библиотеки OpenMP и мето­дики параллельного программирования для многопроцессорных систем читатель найдет в изданиях [2, 3, 4, 5], указанных в списке литературы.
1.2. Параллельные вычисления с разделенной памятью
В высокопроизводительных вычислениях большую роль играют вычислительные системы с разделенной. памятью Схема такой системы представлена на рис. 1.5. Каждый процессор имеет собственную опера­тивную память и доступ к одному или нескольким коммуникационным каналам.
В настоящее время существуют две различные реализации систем с распределенной памятью: массивно-параллельные компьютеры и вы- числительные кластеры. Массивно-параллельный компьютер являет­ся отдельным инженерным решением, объединяющим в рамках одного компьютера большое число вычислительных узлов. Каждый вычисли­тельный узел состоит из процессора, оперативной памяти и коммуника­ционного устройства. С помощью своих коммуникационных устройств вычислительные узлы соединены в единую вычислительную сеть по­средством высокоскоростных каналов передачи данных. Каждый узел может иметь доступ к нескольким каналам передачи данных и, таким образом, непосредственно общаться с несколькими «соседними» вычис­лительными узлами. Порядок соединения вычислительных узлов на­зывается топологией. Примером массивно-параллельного компьютера является семейство суперкомпьютеров Cray T3D/T3E, использующих для соединения вычислительных узлов топологию трехмерного тора. Такая топология гарантирует для каждого вычислительного узла непо­средственную связь с шестью «соседями».
Более доступной системой параллельных вычислений для совре­менного исследователя является вычислительный кластер. Как прави-
18
Процессор
Данные
Процессор
Данные
Данные
Данные
Данные
Данные
Процессор
Память
Память
Память
Коммуникационный канал
Рис. 1.5. Схема параллельной вычислительной системы с разделенной памятью
ло, вычислительный кластер состоит из нескольких компьютеров, со­единенных в локальную вычислительную сеть. Чаще всего использу­ется сеть Ethernet, а связь компьютеров осуществляется с помощью сетевых коммутаторов. При использовании кластера становятся очень дорогими операции обмена данными между вычислительными узла­ми и синхронизации вычислительных процессов. Это надо учитывать при создании параллельной программы. Программист обычно не вза­имодействует непосредственно с каждым компьютером и не управля­ет вручную схемами передачи данных от компьютера к компьютеру. Напротив, согласованной работой компьютеров в вычислительном кла­стере управляет программа-посредник, реализующая ту или иную тех­нологию параллельных вычислений. Одной из распространенных тех­нологий программирования для параллельных вычислительных систем с распределенной памятью в настоящее время является система пере- дачи сообщений, зафиксированная в стандарте MPI (Message Passing Interface). Существуют библиотеки к различным языкам программиро­вания и управляющие среды для этого стандарта практически для всех
19
современных операционных систем.
С помощью управляющей среды все параллельные вычислитель­ные процессы собраны в группы, называемые также коммуникаторами. Передача сообщения от процесса возможна либо другому конкретному процессу, либо всем процессам в коммуникаторе. Возможна как блоки- рующая передача, при которой работа передающего процесса приоста­навливается до момента получения сообщения адресатами, так и небло- кирующая передача, при которой работа передающего процесса продол­жается как только сообщение принято к передаче управляющей средой.
Заметим, что полноценное изучение технологии MPI требует от­дельного руководства. Поэтому мы отсылаем читателя к учебниками и монографиям [3, 4, 5, 27]. В разделе 4.5 также приводится текст про­граммы с использованием MPI для вычисления определенного много­мерного интеграла методом Монте-Карло и пояснения к ней.
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]