Этот пример показывает основы работы с spmd операторами, и как они обеспечивают интерактивные средние значения выполнения параллельных расчетов. Мы делаем это путем выполнения относительно простых расчетов, чтобы аппроксимировать пи.
Связанная документация:
spmd
в руководстве пользователя Parallel Computing Toolbox™
Связанные примеры:
Код, показанный в этом примере, может быть найден в этой функции:
function paralleldemo_quadpi_mpi
Мы намереваемся использовать факт это
аппроксимировать пи путем аппроксимации интеграла слева.
Мы намереваемся иметь параллельный пул, выполняют вычисления параллельно, и использовать spmd
ключевое слово, чтобы отметить параллельные блоки кода. Мы сначала смотрим на размер параллельного пула, который в настоящее время открыт.
p = gcp; p.NumWorkers
ans = 12
Мы аппроксимируем пи числовым интегралом 4/(1 + x^2)
от 0 до 1.
type pctdemo_aux_quadpi.m
function y = pctdemo_aux_quadpi(x) %PCTDEMO_AUX_QUADPI Return data to approximate pi. % Helper function used to approximate pi. This is the derivative % of 4*atan(x). % Copyright 2008 The MathWorks, Inc. y = 4./(1 + x.^2);
Мы делимся, работа между рабочими (лаборатории) при наличии каждого рабочего вычисляют интеграл функции на подынтервале [0, 1] как показано в изображении.
Мы задаем переменные a
и b
на всех рабочих, но позволяют их значениям зависеть от labindex
так, чтобы интервалы [a, b] соответствовали показанным на рисунке подынтервалам. Мы затем проверяем, что интервалы правильны. Обратите внимание на то, что код в теле spmd оператора выполнен параллельно на всех рабочих в параллельном пуле.
spmd a = (labindex - 1)/numlabs; b = labindex/numlabs; fprintf('Subinterval: [%-4g, %-4g]\n', a, b); end
Lab 1: Subinterval: [0 , 0.0833333] Lab 2: Subinterval: [0.0833333, 0.166667] Lab 3: Subinterval: [0.166667, 0.25] Lab 4: Subinterval: [0.25, 0.333333] Lab 5: Subinterval: [0.333333, 0.416667] Lab 6: Subinterval: [0.416667, 0.5 ] Lab 7: Subinterval: [0.5 , 0.583333] Lab 8: Subinterval: [0.583333, 0.666667] Lab 9: Subinterval: [0.666667, 0.75] Lab 10: Subinterval: [0.75, 0.833333] Lab 11: Subinterval: [0.833333, 0.916667] Lab 12: Subinterval: [0.916667, 1 ]
Мы позволяем всем рабочим теперь использовать квадратурный метод MATLAB, чтобы аппроксимировать каждый интеграл. Они все работают с той же функцией, но с различными подынтервалами [0,1] показанный на рисунке выше.
spmd myIntegral = integral(@pctdemo_aux_quadpi, a, b); fprintf('Subinterval: [%-4g, %-4g] Integral: %4g\n', ... a, b, myIntegral); end
Lab 1: Subinterval: [0 , 0.0833333] Integral: 0.332565 Lab 2: Subinterval: [0.0833333, 0.166667] Integral: 0.32803 Lab 3: Subinterval: [0.166667, 0.25] Integral: 0.31932 Lab 4: Subinterval: [0.25, 0.333333] Integral: 0.307088 Lab 5: Subinterval: [0.333333, 0.416667] Integral: 0.292162 Lab 6: Subinterval: [0.416667, 0.5 ] Integral: 0.275426 Lab 7: Subinterval: [0.5 , 0.583333] Integral: 0.257707 Lab 8: Subinterval: [0.583333, 0.666667] Integral: 0.239713 Lab 9: Subinterval: [0.666667, 0.75] Integral: 0.221994 Lab 10: Subinterval: [0.75, 0.833333] Integral: 0.204949 Lab 11: Subinterval: [0.833333, 0.916667] Integral: 0.188836 Lab 12: Subinterval: [0.916667, 1 ] Integral: 0.173804
Рабочие все вычислили свои фрагменты интеграла функции, и мы добавляем результаты вместе, чтобы сформировать целый интеграл по [0, 1]. Мы используем gplus
функция, чтобы добавить myIntegral
через всех рабочих и возвращают сумму на всех рабочих.
spmd piApprox = gplus(myIntegral); end
Начиная с переменной piApprox
был присвоен внутренней части spmd оператор, это доступно на клиенте как Составной объект. Составные объекты напоминают массивы ячеек с одним элементом для каждого рабочего. Индексация в Составной объект возвращает соответствующее значение от рабочего клиенту.
approx1 = piApprox{1}; % 1st element holds value on worker 1. fprintf('pi : %.18f\n', pi); fprintf('Approximation: %.18f\n', approx1); fprintf('Error : %g\n', abs(pi - approx1))
pi : 3.141592653589793100 Approximation: 3.141592653589792700 Error : 4.44089e-16