Вы находитесь на странице: 1из 38

Лабораторная 5

Использование MATLAB в параллельном режиме


Задание.
1. Выполнить решение задачи с помощью ин6терактивного режима для
любого числа процессов
2. Выполнить решение задачи с помощью m-файла и функции для
любого числа процессов
3. Выполнить решение задачи с помощью обмена сообщениями для
любого числа процессов
4. Выполнить решение с помощью spmd и обмена сообщениями для
любого числа процессов
Варианты для заданий 1-2
Суммы
x x
2i i
1. 15 20
∑ ∑
x
2i +1


12

2.
i=3
( 2 i )! 3.
i= 1
(i) !
i=2
( 2 i+1 )!
x
2i 20 50
1
∑ (−1 ) 1
i
6
∑ (−1 )
i

4.
i=2
i! 5.
i= 0
i! 6.
i=0
i!
7
8. 9.
∑ (−1) x
i i
40
7. i=3 ∑ (−1) (i+1) x
i i
100 (i+1 )( i+2 )
∑ (−1) x
i i

i=0 i =10
2
60
∑ix
i

10. i=1

Интегралы
1 1 π /4

∫ 1+dxx2 ∫ 1+dxx ∫ sin 4 xdx


0 . 2. 0 . 3. 0

1 e e1
dx
∫ ∫ ln xdx ∫ ln( x+1)dx
4. 0 √1+x 2
. 5. 0 . 6. 0 .

π /2 1 π
e x dx
∫ x cos xdx ∫ 1+e 2 x ∫ cos3 xdx
7. 0 . 8. 0 . 9. 0 .
π /4 π /2 1

∫ cosdxx ∫ dx
1+sin x
∫ arctgxdx
10. 0 . 11. 0 . 12. 0 .

1 √2 2 π /4
dx
∫ 1+e x ∫ arcsin xdx ∫ tgxdx
13. 0 . 14. 0 . 15. 0

π/2 1 1

∫ ctgxdx ∫ xe dx
x
∫ √ 1+x dx
16. π /4 . 17. 0 . 18. 0
Варианты для заданий 3-4
1. Даны последовательности чисел А = {а0…аn–1} и С = {с0…сn–1}.
Создать приложение, определяющее, совпадают ли поэлементно элементы
массивов А и С.
2. Дана последовательность чисел С = {с0…сn–1}. Дан набор из N пар
кодирующих чисел (ai,bi), т.е. все ai заменяются на bi. Создать приложение,
кодирующее последовательность С следующим образом: массив разделяется
на подмассивы и каждый процесс осуществляет кодирование своего
подмассива.
3. Дана последовательность чисел С = {с0…сn–1} и число b. Создать
приложение для определения количества вхождений числа b в массив C.
4. Дана последовательность натуральных чисел {a0…an–1}. Создать
приложение для поиска произведения чисел a0*а1*…*an–1.
5. Дана последовательность натуральных чисел {a0…an–1}. Создать
приложение для поиска максимального ai.
6. Дана последовательность натуральных чисел {a0…an–1}. Создать
приложение для поиска минимального ai.
7. Дана последовательность натуральных чисел {a0…an–1}. Создать
приложение для поиска всех ai, являющихся простыми числами.
8. Дана последовательность натуральных чисел {a0…an–1}. Создать
приложение для поиска всех ai, являющихся квадратами любого
натурального числа.
9. Дана последовательность натуральных чисел {a0…an–1}. Создать
приложение для вычисления выражения a0-а1+a2-а3+a4-а5+...
10. Дана последовательность натуральных чисел {a0…an–1}. Создать
приложение для поиска суммы ∑ai, где ai – четные числа.
11. Даны результаты сдачи экзамена по N студенческим группам.
Требуется создать приложение, вычисляющее средний балл. Процессы
должны осуществлять вычисления параллельно по группам.
12. Охранное агентство разработало новую систему управления
электронными замками. Для открытия двери клиент обязан произнести
произвольную фразу из 25 слов. В этой фразе должно встречаться заранее
оговоренное слово, причем только один раз. Требуется создать приложение,
управляющее замком. Процессы должны осуществлять сравнение
параллельно по словам.
13. Дан список студентов по группам. Требуется создать приложение
для определения количества студентов с фамилией Иванов. Процессы
должны осуществлять поиск совпадений по группам параллельно.
14. Среди студентов университета проведен опрос с целью определения
процента студентов, знающих точную формулировку правила Буравчика. В
результате собраны данные о количестве знатоков на каждом факультете по
группам. Известно, что всего обучается 10000 студентов. Требуется создать
приложение для определения процента знающих правило Буравчика
студентов. Каждый процесс должен осуществлять поиск количества знатоков
по факультету. Искомый процент определяет главный процесс.
15. Даны результаты сдачи экзамена по группам. Требуется создать
приложение, вычисляющее количество двоечников и отличников. Процессы
должны осуществлять вычисления параллельно по группам.
16. Руководство заготовительной компании «Рога и Копыта» проводит
соревнование по заготовке рогов среди своих региональных отделений. Все
данные по результатам заготовки рогов (заготовитель, его результат)
хранятся в общей базе данных по отделениям. Требуется создать
приложение для поиска лучшего заготовителя. Процессы должны
осуществлять поиск победителя параллельно по отделениям. Главный
процесс определит победителя.
Основные характеристики среды MATLAB
Система MATLAB (сокращение от MATrix LABoratory - матричная лабо-
ратория) представляет собой интегрированную программную среду для
выполнения численных расчетов, компьютерного моделирования и
вычислительных экспериментов, охватывающих в том или ином объеме
различные области классической и современной математики, а также
широчайший спектр инженерных приложений.
Архитектурно система MATLAB состоит из базовой программы и
нескольких десятков так называемых пакетов расширения, которые в своей
совокупности обеспечивают исключительно широкий диапазон решаемых
задач. Интеграция всех этих средств в единой рабочей среде обеспечивает
необходимую гибкость использования сотен встроенных функций,
реализующих разнообразные математические процедуры и вычислительные
алгоритмы.
Основные элементы графического интерфейса системы MATLAB
Каждый отдельный запуск системы MATLAB называется сеансом работы с
ней.
При вызове Matlab ее интерфейс можно настроить по своему желанию.
Наиболее удобно видеть все окна в различных закладках. Это достигается
выполнением пункта меню Desktop, DesktopLayout, AllTabbed. При этом
можно сделать невидимыми закладки Command History и Profile и окно будет
следующего вида:

Закладки имеют следующий смысл:


Command Window – основное окно команд. Окно команд предназначено для
взаимодействия с системой в режиме командной строки.
Окно команд используется для ввода команд и функций с необходимыми
аргументами, задания значений переменных и отображения результатов
выполненных расчетов. С появлением новых версий MATLAB были
разработаны специальные графические интерфейсы пользователя (GUI —
Giaphic User Interface), ориентированные на решение отдельных классов
задач. Тем не менее, окно команд продолжает играть ключевую роль при
работе с системой MATLAB, поскольку обеспечивает полный контроль над
процессом решения тех или иных задач.
Для гибкого и полного использования возможностей системы MATLAB
следует знать функциональные возможности окна команд. Говоря о процессе
работы в данном окне, будем называть этот режим режимом командной
строки или сокращенно — режимом команд. Напротив, использование
специальных графических интерфейсов GUI для решения отдельных классов
задач будем называть графическим или интерактивным режимом работы.
Current Folder – содержимое текущей папки, которая устанавливается в
верхней части экрана
Workspace – рабочая область – все переменные, созданные в ходе сеанса
Help – окно помощи, которое можно просматривать по оглавлению или
выделив команду или фрагмент текста в программе и нажав клавишу F1
Отдельно по командам меню File, New, Blank M-file и File, New, Function M-
file открывается окно редактора скриптов (m-файлов), в которых можно
записывать любые наборы команд Скрипт сохраняется как файл с
расширением .m и запускается на выполнение нажатием зеленой треугольной
кнопки:

Результаты выполнения скрипта можно видеть в командном окне, в том


числе и ошибки, помеченные красным цветом.
Скрипты работают с данными из рабочей области. Переменные,
используемые в скриптах, являются глобальными, то есть они действуют
одинаково в командах сессии и внутри программного блока, которым
является скрипт.

Средства языка программирования MATLAB


Язык программирования системы MATLAB имеет следующие средства:
 данные различного типа;
 константы и переменные;
 операторы, включая операторы математических выражений;
 встроенные команды и функции;
 функции пользователя;
 управляющие структуры;
В MATLAB определены следующие основные типы данных, в общем случае
представляющих собой многомерные массивы:
 single — числовые массивы с числами одинарной точности; 
 double — числовые массивы с числами удвоенной точности; 
 char — строчные массивы с элементами-символами;
 сеll — массивы ячеек; ячейки, в свою очередь, тоже могут быть
массивам
Создание массивов ячеек
Массив ячеек — наиболее сложный тип данных в системе MATLAB. Это
массив, элементами которого являются ячейки, содержащие любые типы
массивов, включая массивы ячеек. Отличительным атрибутом массивов
ячеек является задание содержимого последних в фигурных скобках {}.
Создавать массивы ячеек можно с помощью оператора присваивания.
Существуют два способа присваивания данных отдельным ячейкам:
 индексацией ячеек;
 индексацией содержимого.
Рассмотрим первый способ. Для этого создадим файл-сценарий с именем
се.m:
А( 1.1)={'Курить вредно!'}; 
А(1.2)={[1 2;3 4]}; 
A(2,1)={2+3i}; 
А(2.2)={0:0.1:1}

Визуализация массивов ячеек


Для отображения массива ячеек С служит функция celldlsp(C). Она дает
рекурсивное отображение содержимого массива ячеек С. Например, для
ранее созданного массива ячеек А получится следующее:
» celldisp(A)
А{1.1}=
Курить вредно!
А{2.1}=
 2.0000 + 3.0000i
А{1,2} =
12
34
А{2,2} -Columns 1 through 7
0 0.1000 0.2000 0.3000 0.4000 0.5000 0.6000 
Columns 8 through 11 
0.7000 0.8000 0.9000 1.0000
Управляющие структуры
Условный оператор
Условный оператор if в общем виде записывается следующим образом:
if Условие 
Инструкции_1
elself Условие 
Инструкции_2 
else 
Инструкции_3 
end
Эта конструкция допускает несколько частных вариантов. В простейшем
случае:
if Условие
Инструкции
end
Пока Условие возвращает логическое значение 1 (то есть «истина»),
выполняются Инструкции, составляющие тело структуры if...end. При этом
оператор end указывает на конец перечня инструкций. Инструкции в списке
разделяются оператором , (запятая) или ; (точка с запятой). Если Условие не
выполняется (дает логическое значение 0, «ложь»), то Инструкции также не
выполняются.
Еще одна конструкция
if Условие 
Инструкции_1 
else 
Инструкции_2 
end
выполняет Инструкции_1, если выполняется Условие, или Инструкции_2 в
противном случае.
Условия записываются в виде:
Выражение_1 Оператор_отношения Выражение_2,
причем в качестве Операторов_отношения используются следующие
операторы: ==, <, >, <=, >= или ~=. Все эти операторы представляют собой
пары символов без пробелов между ними.

Конструкция переключателя
Для осуществления множественного выбора (или ветвления) используется
конструкция с переключателем типа switch:
switch switch_Bыражение 
case саsе_Выражение 
Список_инструкций
case {саsе_Выражение1, Саsе_выражение2, саsе_ВыражениеЗ....} 
Список_инструкций
Otherwise
Список_инструкций
end
Если выражение после заголовка switch имеет значение одного из выражений
саsе_Выражение..., то выполняется блок операторов case, в противном случае
— список инструкций после оператора otherwise. При выполнении блока case
исполняются те списки инструкций, для которых сазе_Выражение совпадает
со switch_выpaжением. сазе_Выражение может быть числом, константой,
переменной, вектором ячеек или даже строчной переменной. В последнем
случае оператор case истинен, если функция strcmp (значение, выражение)
возвращает логическое значение «истина».
Поясним применение оператора switch на примере m-файла swl.m:
switch var 
case {1,2,3}
disp(‘Первый квартал') 
case {4,5,6}
disp('Второй квартал') 
case {7,8,9}
d.isp( 'Третий квартал') 
case {10.11,12}
disp(‘Четвертый квартал') 
otherwise
disp('Ошибка в задании') 
end
Эта программа в ответ на значения переменной van — номера месяца —
вычисляет, к какому кварталу относится заданный месяц, и выводит
соответствующее сообщение:
» var=2;
» swl
Первый квартал 
» var=4;swl 
Второй квартал 
» var=7:swl 
Третий квартал 
» var=12;swl 
Четвертый квартал
» var=-l;swl 
Ошибка в задании

Циклы типа for...end


 
Циклы типа for...end обычно используются для организации вычислений с
заданным числом повторяющихся циклов. Конструкция такого цикла имеет
следующий вид:
for vаг=Выражение. Инструкция. .... Инструкция end
Выражение чаще всего записывается в виде s:d:e, где s — начальное значение
переменной цикла var, d — приращение этой переменной и е — конечное
значение управляющей переменной, при достижении которого цикл
завершается. Возможна и запись в виде s :е (в этом случае d=l). Список
выполняемых в цикле инструкций завершается оператором end.
Следующие примеры поясняют применение цикла для получения квадратов
значений переменной цикла:
» for 1=1:5 i^2. end; 
ans =

ans =

ans =

ans =
16 
ans =
25
» for x=0:.25:1 Х ^ 2, end: 
ans =

ans =
0.0625 
ans =
0.2500
ans =
0.5625 
ans =
1
Оператор continue передает управление в следующую итерацию цикла,
пропуская операторы, которые записаны за ним, причем во вложенном цикле
он передает управление на следующую итерацию основного цикла. Оператор
break может использоваться для досрочного прерывания выполнения цикла.
Как только он встречается в программе, цикл прерывается. Возможны
вложенные циклы, например:
for i=1:3
for j=l:3
A(i,j)=i+j;
end 
end
В результате выполнения этого цикла (файл for2.m) формируется матрица А:
» for2 
»А
А=
234
345
4 5 6 
»
Следует отметить, что формирование матриц с помощью оператора :
(двоеточие) обычно занимает намного меньше времени, чем с помощью
цикла. Однако применение цикла нередко оказывается более наглядным и
понятным. MATLAB допускает использование в качестве переменной цикла
массива А размера тхп.
» А=[1 2 3;4 5 6] 
А=
123
4 5 6 
» for var=A
Var;
end 

Циклы типа while...end

Цикл типа while выполняется до тех пор, пока выполняется Условие:


while Условие
Инструкции
end
Досрочное завершение циклов реализуется с помощью операторов break или
continue.

Диалоговый ввод
Приведем простой пример диалоговой программы:
% Вычисление длины окружности с диалоговым вводом радиуса
r=0;
while r>=0,
r=input('Введите радиус окружности r=');
if r>=0
disp(' Длина окружности l=');
disp(2*pi*r),
end 
end
Эта программа служит для многократного вычисления длины окружности по
вводимому пользователем значению радиуса г. Простейший диалог
реализован с помощью команды input:
input(‘Введите радиус окружности r='):
При выполнении этой команды вначале выводится запрос в виде строки,
затем происходит остановка работы программы и ожидается ввод значения
радиуса г (в общем случае числа). Ввод, как обычно, подтверждается
нажатием клавиши Enter, после чего введенное число присваивается
переменной г. Следующие строки
if r>=0
disp(' Длина окружности l = ');
disp(2*pi*r);
end
с помощью команды disp при r>=0 выводят надпись «Длина окружности 1=»
и вычисленное значение длины окружности.
Пока r>=0. цикл повторяется. Но стоит задать r<0, вычисление длины
окружности перестает выполняться, а цикл завершается.
Функция input может использоваться и для ввода произвольных строковых
выражений. При этом она задается в следующем виде:
input('Комментарий'. ‘s’)
При выполнении этой функции она останавливает вычисления и ожидает
ввода строкового комментария. После ввода возвращается набранная строка.
Это иллюстрирует следующий пример:
» S=input('Введите выражение ','s') % (Вводим) 2*sin(l) 
S=
2*sin(l) 
» eval(S) 
ans = 
1.6829
Функция eval позволяет вычислить выражение, заданное (полученное от
функции input) в символьном виде. Вообще говоря, возможность ввода
любого символьного выражения в сочетании с присущими языку
программирования MATLAB управляющими структурами открывает путь к
созданию диалоговых программ любой сложности

Функции в MATLAB(М-функции)
М-функции являются M-файлами, которые допускают наличие входных и
выходных аргументов. Они работают с переменными в пределах собственной
рабочей области, отличной от рабочей области системы MATLAB.
Пример
Функция average - это достаточно простой M-файл, который вычисляет
среднее значение элементов вектора:
function y = average (x)
% AVERAGE Среднее знач0ение элементов вектора.
[m,n] = size(x);
if (~((m == 1) | (n == 1)) | (m == 1 & n == 1))
        error('Входной массив должен быть вектором’)
end
y =sum(x)/length(x);            % Собственно вычисление
Эти команды нужно записать в M-файл, именуемый average.m. Функция
average допускает единственный входной и единственный выходной
аргументы. Для того чтобы вызвать функцию average, надо ввести
следующие операторы:
z=1:99;
average(z)
ans = 50
Структура М-функции.
M-функция состоит из:
 строки определения функции;
 первой строки комментария;
 тела функции;
 строчных комментариев;
Строка определения функции. Строка определения функции сообщает
системе MATLAB, что файл является М-функцией, а также определяет
список входных аргументов.
Строка определения функции average имеет вид:
function y = average(x)
Здесь:
1. function - ключевое слово, определяющее М-функцию;
2. y - выходной аргумент;
3. average - имя функции;
4. x - входной аргумент.
Каждая функция в системе MATLAB содержит строку определения функции,
подобную приведенной.
Если функция имеет более одного выходного аргумента, список выходных
аргументов помещается в квадратные скобки. Входные аргументы, если они
присутствуют, помещаются в круглые скобки. Для отделения аргументов во
входном и выходном списках применяются запятые.
Пример
function [x, y, z] = sphere(theta, phi, rho)
Первая строка комментария. Для функции average первая строка
комментария выглядит так:
% AVERAGE Среднее значение элементов вектора
Это - первая строка текста, которая появляется, когда пользователь набирает
команду help <имя_функции>. Поскольку эта строка содержит важную
информацию об M-файле, она должна быть тщательно составлена.
Тело функции. Тело функции содержит код языка MATLAB, который
выполняет вычисления и присваивает значения выходным аргументам.
Операторы в теле функции могут состоять из вызовов функций,
программных конструкций для управления потоком команд, интерактивного
ввода/вывода, вычислений, присваиваний, комментариев и пустых строк.
Пример
Тело функции average включает ряд простейших операторов
программирования:
Оператор вызова функции size [m, n] = size(x);
Начало оператора if if(~((m==1)|(n==1))|(m == 1 & n == 1))
Сообщение об ошибке   Error('Input должно быть вектором')
Конец оператора if end
Вычисление и присваивание y = sum(x)/length(x);
Как уже говорилось ранее, комментарии отмечаются знаком (%). Строка
комментария может быть размещена в любом месте M-файла, в том числе и в
конце строки.
Имена М-функций. В системе MATLAB на имена М-функций налагаются те
же ограничения, что и на имена переменных - их длина не должна превышать
31 символа. Имена М-функций должны начинаться с буквы; остальные
символы могут быть любой комбинацией букв, цифр и подчеркиваний.
Имя файла, содержащего М-функцию, составляется из имени функции и
расширения “.m”.
Средства MATLAB для выполнения параллельных вычислений
MATLAB Parallel Computing Toolbox (PCT) – это набор специальных
средств и функций для написания параллельных алгоритмов и организации
распределенных вычислений, который позволяет использовать как локальные
многопроцессорные, так и распределенные вычислительные ресурсы. PCT
предназначен для разработки параллельных алгоритмов, для формирования
распределенной задачи, передачи её на сервер и для приема результатов
вычислений. Основная задача формулируется на языке MATLAB и может
использовать функции любых пакетов расширения. Также пакет
поддерживает интерфейс передачи сообщений MPI, что позволяет
разрабатывать на MATLAB эффективные приложения с параллельными
вычислениями. Серверная часть пакета - MATLAB Distributed Computing
Server (DST) обеспечивает исполнение основной задачи на удаленных
сессиях MATLAB. Планировщик MathWorks Job Manager распределяет ежду
исполнителями подзадачи. Он координирует выполнение заданий и
асинхронно распределяет задачи рабочим станциям – исполнителям.
Планировщик устанавливается на любой машине находящейся в сети и
может обрабатывать задания различных пользователей различных платформ.
Принцип динамического лицензирования позволяет использовать при
разработке распределенных приложений любые пакеты расширений
MATLAB имеющиеся на клиентской стороне.
Работа (job) – это некоторая сложная операция, которую нужно выполнить в
сеансе MATLAB. Работа разбивается на сегменты, называемые заданиями
(tasks). Пользователь решает, как лучше разделить работу на задания. Работа
делится на идентичные задания, но они выполняются не одинаково.
Сессия MATLAB , в которой определены работа и задания, называется
клиентской сессией (client). Клиент использует PCT для определения работы
и заданий. MATLAB DST выполняет работу путем вычисления заданий и
возврата результата клиентской сессии.
job manager- это часть программного обеспечения, которая координирует
выполнение работ и вычисление их заданий. job manager распределяет
задания для выполнения индивидуальным сессиям MATLAB, называемым
рабочими (workers).
Можно конфигурировать один компьютер как клиента, рабочего или
планировщика ( job manager).

Способы организации параллельных вычислений в MATLAB


1. Режим pmode, с помощью которого непосредственно из командного окна
MATLAB становится возможным обращение к процессам workers, просмотр
их локальных переменных, обмен данными между ними. В режиме pmode
команды, вводимые в рабочем окне MATLAB, будут исполняться всеми
рабочими процессами, называемыми также labs, ассоциированными с
соответствующим jobmanager.
При окончании сессии pmode, ее работа разрушается и вся информация и
данные из labs теряются. Начало любой сессии pmode всегда начинается с
начального состояния.
Режим pmode запускается командой вида
pmode start local 4
При этом начинается выполнение 4 labs, создается параллельная работа для
запуска на этих labs и открывается Parallel Command Window.

Присвоим некоторой переменной значение в строке приглашения pmode.


Значение присвоится во всех labs.
x = pi
Переменная не всегда имеет одно и то же значение на каждой lab. Функция
labindex возвращает номер каждой lab, работающей в параллельной работе. В
примере переменная x получает различные значения в рабочем пространстве
каждой lab.
P>> x = labindex
Получим значение общего числа labs, работающих в текущей параллельной
работе с помощью функции numlabs.
P>> all = numlabs

Создадим воспроизведенный массив на всех labs.


P>> segment = [1 2; 3 4; 5 6]
Назначим уникальное значение массиву в каждой lab в зависимости от
номера lab. Так как он имеет различные значения в каждой lab, это массив
variant.
P>> segment = segment + 10*labindex
До этого момента в примере массивы variant независимы. Используем
функцию codistributed.build для объединения частей массива в сцепленный
массив, распределенный между labs
P>> codist = codistributor1d(2, [2 2 2 2], [3 8])
Объект codistributor1d указывает, что массив делится по второму измерению
(столбцы), по 2 столбца в каждом из четырех labs. В каждой lab переменная
segment использует локальную порцию всего массива.
P>> whole = codistributed.build(segment, codist)
Таким образом четыре отдельных массива из 3 строк и 2 столбцов
объединяются в один массив из 3 строк и 8 столбцов типа codistributed.
При использовании codistributed массива с именем whole каждая lab
использует при вычислениях только свою порцию или сегмент массива, а не
весь массив.
P>> whole = whole + 1000
Хотя codistributed массив позволяет оперировать с его содержимым целиком,
можно использовать функцию getLocalPart для доступа к порции такого
массива в конкретной lab.
P>> section = getLocalPart(whole)

Переменная section - массив типа variant, так как он различен в каждой lab.
Если есть необходимость использовать весь массив в одном рабочем
пространстве, следует использовать функцию gather.
P>> combined = gather(whole)
Заметим, что это объединяет весь массив в рабочем пространстве всех lab.
Можно собрать массив в рабочем пространстве только одного.
X = gather(C, номер lab) конвертирует codistributed массив C в variant массив
X так, что все данные содержатся в lab с указанным номером, а X размера 0
строк и 0 столбцов содержится во всех остальных lab.
Так как вывод во всех lab обычно невозможен, для графического
использования данных следует получить данные в рабочем пространстве
клиента. Копирование массива в клиентское пространство выполняется
командой
pmode lab2client combined 1
, выполняемой в окне команд клиента
>>pmode lab2client combined 1
>> combined
combined =
1011 1012 1021 1022 1031 1032 1041 1042
1013 1014 1023 1024 1033 1034 1043 1044
1015 1016 1025 1026 1035 1036 1045 1046
Со многими матричными функциями можно оперировать, используя
codistributed массивы. Например, функция eye создает единичную матрицу
(по диагонали 1, остальные 0). Можно создать codistributed единичную
матрицу с помощью команды, выполняемой в окне Parallel Command
Window.
P>> distobj = codistributor1d();
P>> I = eye(6, distobj)
P>> getLocalPart(I)
Вызов функции codistributor1d без аргументов определяет распределение по
умолчанию, которое является распределением по столбцам, причем в каждый
lab попадет столько столбцов, сколько возможно.

Покажем решение задачи вычисления числа π как значения определенного


интеграла

Чтобы проинтегрировать функцию , следует воспользоваться


тем свойством, что каждый из доступных рабочих процессов может
интегрировать функцию Р(х) на своем участке интервала.
Очевидно, что первым шагом решения задачи должно быть распространение
функции F(х) на все рабочие процессы. Вводим команду
F=@(x) 4./(1+x.^2)
и команды, определяющие интервал интегрирования для каждого процесса
a=(labindex-1)/numlabs
b=labindex/numlabs

Теперь, воспользовавшись функцией quadl(F,a,b), в качестве параметров


которой передаются подынтегральная функция и границы интегрирования,
вычислим значение определенного интеграла в каждом из рабочих
процессов.
>>my=quadl(F,a,b)

После того как в каждой сессии определена переменная my, необходимо


воспользоваться функцией gplus и произвести глобальное суммирование
переменной my по всем процессам.
gplus(х) возвращает сумму значений переменной х по всем процессам.
Результат тиражируется на всех сессиях процессов.
piA=gplus(my)
Если требуется, переменную, хранящуюся в сессии рабочего процесса,
можно экспортировать в текущую (пользовательскую) сессию МАТLАВ.
Команда lab2client позволяет копировать определенную переменную из
любого процесса в пользовательскую сессию.
>>pmode lab2client piA 1
>> piA
piA = 3.1416
Итогом рассмотренной задачи является переменная piA, определенная в
локальной сессии МАТЪАВ. Для сравнения полученного значения со
значением константы рi, которое хранится в системе МАТЬАВ, рассмотрим
разность piА - pi
аns =2.4866е-010
Выход из режима pmode и возврат в сеанс клиента происходит по команде
P>> pmode exit
1. Режим создания параллельных задач
В этом режиме с помощью команд создаются работа, задача и запускается
некоторая функция.
При запуске сеанса MATLAB ему доступна только конфигурация 'local',
позволяющая производить вычисления на локальном компьютере.
Ее можно настраивать с помощью пункта меню Parallel, Manage
Configuration
Двойной щелчок по конфигурации открывает окно настройки

В нем следует задать число рабочих сеансов, доступное планировщику


Вначале отыскивается имеющийся в текущей конфигурации планировщик
(jobmanager) с помощью команды вида:
jm = findResource('scheduler','type','jobmanager','configuration','local')
Одним из методов объекта jobmanager является createParallelJob.
pjob=jm.createParallelJob();
Переменная pjob является ссылочной переменной и ссылается на
определенный участок оперативной памяти, выделенной для системного
процесса планировщика. Свойства объекта pjob можно получить с помощью
команды:
get(pjob)
Configuration: ''
Name: 'Job27'
ID: 27
UserName: 'Администратор'
Tag: ''
State: 'pending'
CreateTime: 'Mon Nov 05 17:15:13 GMT+09:00 2012'
SubmitTime: ''
StartTime: ''
FinishTime: ''
Tasks: [0x1 double]
FileDependencies: {0x1 cell}
PathDependencies: {0x1 cell}
JobData: []
Parent: [1x1 distcomp.localscheduler]
UserData: []
MaximumNumberOfWorkers: 5
MinimumNumberOfWorkers: 1
В силу того, что задача будет отправляться на вычисление через
планировщик jm (у которого в свойствах указано, сколькими занятыми и
сколькими свободными рабочими процессами он обладает в данный момент
времени), уже в самой задаче (в объекте pjob) должно быть указано, сколько
свободных процессов требуется планировщику для начала вычислений,
описанных в задаче pjob.
Значение свойств MaximumNumberOfWorkers и MinimumNumberOfWorkers
есть положительное целое число. Установим его равным двум, то есть
вычисления в задаче pjob начнутся, как только у планировщика jm появятся
два свободных рабочих процесса.
Запись значений этим свойствам можно с помощью команд
set(pjob,'MinimumNumberOfWorkers',2);
set(pjob,'MaximumNumberOfWorkers',2);
Параллельное задание есть не что иное, как m-файл, который будет
исполняться одновременно всеми рабочими процессами. Передать m-файл
напрямую рабочему процессу нельзя, для этой цели необходимо
использовать объект Task (параллельное задание). Объект Task является
дочерним объектом по отношению к объекту paralleljob и может быть создан
посредством метода createTask.
Создадим m-файл и опишем в нем функцию (процедуру), которая будет
выполняться каждым процессом. Пусть это будет вычисление числа pi,
выполненное ранее в режиме pmode:
function piapprox=par_pi(F)
% инициализация
a=(labindex - 1)/numlabs; b=labindex/numlabs;
% вычисление интеграла
myInt=quadl(F,a,b);
% суммирование по всем workers
piapprox=gplus(myInt);
После того как написали m-файл, следует указать в свойстве FileDependencies
объекта pjob имя файла, который будет выполняться рабочими процессами
set(pjob, 'FileDependencies', {'par_pi.m'});
После этого создаем переменную, которая будет является подзадачей. Во
входных параметрах требуется указать переменную - параллельную задачу,
количество выходных аргументов (в рассматриваемом примере - 1) и
входные аргументы {F} (переменная F должна уже быть определена в
локальной сессии MATLAB):
F=@(x) 4./(1+x.^2);
obj = createTask(pjob,'par_pi',1,{F})
Теперь все, что осталось сделать - это выполнить следующий участок кода:
submit(pjob); waitForState(pjob);
Команда submit отправляет задачу pjob планировщику jobmanager. Задача
начинает решаться рабочими процессами не сразу, а только тогда, когда
свободными окажутся столько процессов, сколько указано в свойстве
MinimumNumberOfWorkers. До этого момента задача находится в очереди.
Как только количества свободных процессов оказалось достаточно, рабочие
процессы начинают выполнять один и тот же m-файл. В этот момент
свойство State объекта pjob принимает значение running. Свойство поменяет
свое значение на finished только после того, как задача, описанная в m-файле,
выполнится. Это произойдет после выполнения команды waitForState.
Как только задача поменяла статус на finished, можно воспользоваться
методом getAllOutputArguments и получить данные в локальной сессии
MATLAB.
results = getAllOutputArguments(pjob)
Для завершения параллельной работы выполняется команда
destroy(pjob)

2. Передача сообщений между рабочими сеансами


В приложении PCT системы MATLAB имеется встроенный набор функций
для передачи сообщений между процессами, основанный на интерфейсе
передачи сообщений Message Passing Interface (MPI).

Посылка данных другому lab


labSend(данные любого типа, номер процесса - получателя)
Получение данных от другого lab
данные = labReceive
данные = labReceive(номер lab)
Пример: суммирование элементов массива с подсчетом подсумм в отдельных
рабочих процессах. Запускающий m-файл:
jm = findResource('scheduler','type','jobmanager','configuration','local')
pjob=jm.createParallelJob();
set(pjob,'MinimumNumberOfWorkers',3);
set(pjob,'MaximumNumberOfWorkers',3);
%x=rand(100,1)*10;
x=[1 2 3 4 5 6 7 8 9 10];
set(pjob, 'FileDependencies', {'par_sum.m'});
createTask(pjob,'par_sum',1,{x});
submit(pjob); waitForState(pjob);
results = getAllOutputArguments(pjob)
destroy(pjob)
s=0;
for i=1:length(x)
s=s+x(i);
end
s
Функция par_sum в файле par_sum.m:
function z=par_sum(x)
z=0;
m=length(x);
if ( labindex == 1)
%DataInitialization(x,N);
end
% Вычисление частичной суммы на каждом из процессов
% на каждом процессе суммируются элементы вектора x от i1 до i2
k =fix(m / numlabs);
i1 = k * (labindex-1)+1;
i2 = k * ( labindex );
if ( labindex == numlabs )
i2 = m;
end
ProcSum=0;
for i = i1:i2
ProcSum = ProcSum + x(i);
end
% Сборка частичных сумм на процессе с номером 1
if ( labindex == 1 )
TotalSum = ProcSum;
for i=2:numlabs
ProcSum=labReceive(i);
TotalSum = TotalSum + ProcSum;
end
z=TotalSum;
else
% Все процессы отсылают свои частичные суммы
labSend(ProcSum, 1);
end

3. Запуск одной программы во всех рабочих процессах


SPMD (single program - multiple data, одна программа – много данных)
позволяет незаметно чередовать обычное и параллельное программирование.
Оператор spmd позволяет определить блок кода для запуска на многих
рабочих процессах. Переменные, определенные внутри блока spmd на
различных lab, можно использовать в клиентском процессе как объект
Composite.
"Одна программа" означает, что один и тот же программный код запускается
на различных рабочих процессах. Когда блок spmd завершается (по
оператору end) программа продолжает свою работу на клиенте.
"много данных" означает, что хотя код блока spmd идентичен на всех lab,
каждый рабочий процесс может использовать уникальные данные.
Типичные случаи применения spmd следующие:
 Программы, имеющие длительное время выполнения — spmd
позволяет нескольким lab выполнять алгоритм одновременно.
 Программы, оперирующие с большими наборами данных — spmd
позволяет разделить данные между многими рабочими процессами.

Перед запуском spmd нужно выполнить команду matlabpool для создания


некоторого числа рабочих процессов MATLAB (lab) для выполнения блоков
spmd. lab могут выполняться удаленно на кластере или локально на
клиентской машине. Команда matlabpool запускает столько рабочих
процессов, сколько их определено в конфигурации local.
Можно запустить команду вида matlabpool 3 для запуска конкретного числа
рабочих процессов. Их число на локальном компьютере не более 8.

Когда заканчивается использование пула pool,он закрывается по команде

matlabpool close

Определение блока spmd имеет вид:


spmd
операторы
end

Например, создадим случайную матрицу:


matlabpool 3
spmd
R = rand(4,4);
end
matlabpool close

Каждый lab, использующий spmd, имеет уникальное значение labindex. Это


позволяет определить уникальный фрагмент кода для некоторых lab.

Например, создадим массивы различного размера в зависимости от labindex:

spmd
if labindex==1
R = rand(9,9);
else
R = rand(4,4);
end
end

Загрузим разные файлы в зависимости от abindex и используем одну и ту же


функцию в каждом lab, обрабатывая разные данные:

spmd
labdata = load(['datafile_' num2str(labindex) '.ascii'])
result = MyFunction(labdata)
end

Можно контролировать обмен между lab, передавать данные между ними


использовать массивы codistributed между ними.

Объекты Composite

Объекты Composite в клиентской сессии позволяют напрямую иметь доступ к


значениям данных в lab. Имеется два способа создать Composites:

 Использование функции Composite на клиенте. При этом значения,


назначенные таким элементам, сохраняются в lab.
 Определение переменных внутри блока spmd. После окончания блока
spmd сохраненные значения доступны на клиенте как Composites.

Более употребителен второй способ.

На клиенте Composite имеет один элемент для каждого рабочего процесса.


Например, предположим, что открыт пул из трех рабочих процессов и
запущен блок spmd на этом пуле:
matlabpool 3

spmd % Использует все рабочие процессы


MM = magic(labindex+2); % MM – переменная каждого lab
end
MM{1} % На клиенте MM - Composite с одним элементом на lab
8 1 6
3 5 7
4 9 2

MM{2}
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1

Переменная может быть неопределенной на каком-то lab. Для тех lab, на


которых переменная не определена, соответствующий элемент Composite не
имеет значения. Попытка прочитать этот элемент приводит к ошибке.

spmd
if labindex > 1
HH = rand(4)
end
end
На клиенте:
HH
1: No data
2: class = double, size = [4 4]
3: class = double, size = [4 4]
Еще пример:
spmd
if labindex > 1
BB = rand(labindex)
end
end

Lab 2:
BB =
0.3802 0.7370
0.1215 0.3625
Lab 3:
BB =
0.7895 0.3064 0.7922
0.3299 0.6448 0.8524
0.0525 0.7349 0.9092
На клиенте: BB
BB =
1: No data
2: class = double, size = [2 2]
3: class = double, size = [3 3]

Также можно задать значение элемента Composite на клиенте. При этом


данные передаются на соответствующий lab, даже если он не выполняется в
блоке spmd:

MM{3} = eye(4);

При этом переменная MM уже должна существовать как Composite

Функция Composite объекты Composite без использования блока spmd. Это


может быть полезно для предварительного присвоения значений переменным
на lab перед исполнением блока spmd. Например:

PP = Composite()

PP =

1: No data

2: No data

3: No data

for ii = 1:numel(PP)%numel – число элементов в Composite

PP{ii} = ii
end

>> PP{:}

ans = 1

ans = 2

ans = 3

Если на клиенте задано значение MM{3}, то выполним

spmd
if labindex == 3
MM
end
end
Lab 3:
MM =
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

Данные передаются из lab на клиента, если использовать переменную как


Composite элемент:

M = MM{1} % Преобразование данных из lab 1 в переменную M на клиенте


8 1 6
3 5 7
4 9 2

Присвоение всего объекта Composite другому не приводит к передаче


данных. Вместо этого клиент просто дублирует Composite как ссылку на
соответствующие данные, сохраненные в lab:

NN = MM % Присвоение всего Composite, равного другому без передачи

Однако доступ к элементам Composite для присвоения значений другим


Composite приводит к передаче данных от lab к клиенту. В этом случае
переменная NN должна уже существовать как Composite:

NN{1} = MM{1} % Передача данных клиенту и затем lab


В таблице показано совместное использование клиента и двух рабочих
процессов:
Client Worker 1 Worker 2
a b e| cdf cdf
a = 3; 3- - --- ---
b = 4; 34- --- |---
spmd
c = labindex(); 34- 1-- 2--
d = c + a; 34- 14- 25-
end
e = a + d{1}; 347 14- 25-
c{2} = 5; 347 14- 56-
spmd
f = c * b; 347 144 5 6 20
end
Длительность существования переменной
и последовательность блоков spmd

Значения, сохраненные на lab, сохраняются между блоками spmd. Это


позволяет использовать несколько блоков spmd и продолжать использовать
переменные, определенные в предыдущих блоках spmd.

Значения сохраняются на lab, пока соответствующие объекты Composite не


будут очищены на клиенте или пока пул не будет закрыт. Пример
иллюстрирует продолжительность жизни данных при наличии нескольких
блоков spmd:

matlabpool 4

spmd
AA = labindex; % Начальная установка
end
AA(:) % Composite
[1]
[2]
[3]
[4]
spmd
AA = AA * 2; % Умножение существующего значения
end
AA(:) % Composite
[2]
[4]
[6]
[8]
clear AA % Очмстка на клиенте также очищает все lab

spmd
AA = AA * 2; % Генерируется ошибка
end
matlabpool close

Функции, которые могут использоваться в рабочих процессах и на


клиенте
gcat Глобальное соединение строк

Xs = gcat(X) сцепляет variant массивы X из каждого lab по второму


измерению (по столбцам). Результат распространяется во все lab.
Xs = gcat(X, номер измерения) сцепляет variant массивы X из каждого lab по
указанному измерению.

Пример с 4 labs
Xs = gcat(labindex)

Возвращает Xs = [1 2 3 4] во все четыре lab.

gop глобальное выполнение операции по всем lab

res = gop(@F, x)
res = gop(@F, x, targetlab)

Аргументы
F Функция, которая действует во всех lab.
x Аргумент для функции F, должен быть одной и той же переменной
во всех lab, но может иметь различные значения.
res Переменная для сохранения результата.
targetlab Рабочий процесс, которому возвращается результат.

res = gop(@F, x) вычисляет функцию F по значению x из каждого lab.


Результат дублируется во все lab.

Функция F(x,y) должна принимать два аргумента одного типа и получать


один результат того же типа, так что он может использоваться итеративно, то
есть

F(F(x1,x2),F(x3,x4))

Функция F должна быть ассоциативна, то есть,

F(F(x1, x2), x3) = F(x1, F(x2, x3))

res = gop(@F, x, targetlab) выполняет вычисления и помещает результат в


переменную res на lab, указываемый параметром targetlab. Во всех остальных
lab переменная res устанавливается в значение [].

Примеры

Вычисление суммы всех значений x во всех lab.

res = gop(@plus,x)

Нахождение максимального значения x по всем lab.


res = gop(@max,x)
Можно создать собственную функцию для запуска функцией gop:
matlabpool(4)
spmd
x=labindex
res=gop(@pr,x)
end
res{1}
matlabpool close
Файл pr.m
function z = pr(x,y)
z=x.*y;
end

Измерение времени выполнения фрагмента кода


Это пара команд tic, toc

tic; любые операторы; toc;

измеряет время выполнения операторов. Команда tic начинает отсчет


времени, затем выполняются операторы и toc останавливает таймер, выводя
на экран время выполнения в секундах.

tic; любые операторы; tElapsed=toc; делает то же самое, но запоминает время


выполнения в переменной tElapsed.

tStart=tic; любые операторы; toc(tStart); делает то же самое, но позволяет


запустить несколько счетчиков времени. Результат tic запоминается в
переменной tStart, и затем и используем ту же переменную при вызове toc.
Измерение времени происходит от точки вызова tic и связанной с ней toc и
выводит время в секундах.

tStart=tic; любые операторы; tElapsed=toc(tStart); делает то же самое, что и


предыдущий вариант, но дополнительно запоминает время выполнения в
переменной tElapsed.

Пример. Изменение минимального и среднего времени вычисления суммы


функций Бесселя:

REPS = 1000; minTime = Inf; nsum = 10;


tic;

for i=1:REPS
tStart = tic; total = 0;
for j=1:nsum,
total = total + besselj(j,REPS);
end

tElapsed = toc(tStart);
minTime = min(tElapsed, minTime);
end
averageTime = toc/REPS;

Вам также может понравиться