parfevalВ этом примере показано, как выполнить параллельный сдвиг параметров с помощью parfeval и отправить результаты обратно во время вычислений с помощью DataQueue объект. parfeval не блокирует MATLAB, поэтому можно продолжить работу во время выполнения вычислений.
Пример выполняет зачистку параметров в системе Лоренца обыкновенных дифференциальных уравнений, в отношении параметров, показывает хаотичность этой системы.
yddtz = xy-βx
Определите диапазон параметров, которые требуется исследовать при протягивании параметров.
gridSize = 40; sigma = linspace(5, 45, gridSize); rho = linspace(50, 100, gridSize); beta = 8/3;
Создайте 2-D сетку параметров с помощью meshgrid функция.
[rho,sigma] = meshgrid(rho,sigma);
Создание объекта фигуры и установка 'Visible' кому true чтобы она открылась в новом окне, за пределами живого сценария. Для визуализации результатов сдвига параметров создайте график поверхности. Обратите внимание, что инициализация Z компонент поверхности с NaN создает пустой график.
figure('Visible',true); surface = surf(rho,sigma,NaN(size(sigma))); xlabel('\rho','Interpreter','Tex') ylabel('\sigma','Interpreter','Tex')

Создание пула параллельных работников с помощью parpool функция.
parpool;
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 6).
Чтобы отправить данные от работников, создайте DataQueue объект. Настройте функцию, которая обновляет график поверхности каждый раз, когда работник отправляет данные с помощью afterEach функция. updatePlot функция является вспомогательной функцией, определенной в конце примера.
Q = parallel.pool.DataQueue; afterEach(Q,@(data) updatePlot(surface,data));
После определения параметров можно выполнить параллельный сдвиг параметров.
parfeval работает более эффективно при распределении рабочей нагрузки. Чтобы распределить рабочую нагрузку, сгруппируйте параметры для изучения в разделы. Для этого примера разбейте на однородные секции размера step с помощью оператора двоеточия (:). Результирующий массив partitions содержит границы секций. Обратите внимание, что необходимо добавить конечную точку последнего раздела.
step = 100; partitions = [1:step:numel(sigma), numel(sigma)+1]
partitions = 1×17
1 101 201 301 401 501 601 701 801 901 1001 1101 1201 1301 1401 1501 1601
Для достижения оптимальной производительности попробуйте разбить на следующие разделы:
Достаточно большое, чтобы время вычисления было большим по сравнению с накладными расходами на планирование раздела.
Достаточно маленький, чтобы было достаточно перегородок, чтобы все работники были заняты.
Чтобы представить выполнение функций на параллельных рабочих и сохранить их результаты, используйте будущие объекты.
f(1:numel(partitions)-1) = parallel.FevalFuture;
Разгрузка вычислений для параллельных работников с помощью parfeval функция. parameterSweep - вспомогательная функция, определенная в конце этого сценария, которая решает систему Лоренца на разделе исследуемых параметров. Он имеет один выходной аргумент, поэтому необходимо указать 1 как количество выходов в parfeval.
for ii = 1:numel(partitions)-1 f(ii) = parfeval(@parameterSweep,1,partitions(ii),partitions(ii+1),sigma,rho,beta,Q); end
parfeval не блокирует MATLAB, поэтому можно продолжить работу во время выполнения вычислений. Рабочие вычисляют параллельно и отправляют промежуточные результаты через DataQueue как только они станут доступны.
Если требуется заблокировать MATLAB до parfeval завершает, используйте wait функция на будущих объектах. Использование wait полезна, когда последующий код зависит от завершения parfeval.
wait(f);

После parfeval завершает вычисления, wait завершает и можно выполнить больше кода. Например, постройте график контура результирующей поверхности. Используйте fetchOutputs для извлечения результатов, сохраненных в будущих объектах.
results = reshape(fetchOutputs(f),gridSize,[]); contourf(rho,sigma,results) xlabel('\rho','Interpreter','Tex') ylabel('\sigma','Interpreter','Tex')

Если для сдвига параметров требуется больше вычислительных ресурсов и у вас есть доступ к кластеру, вы можете увеличить parfeval вычисления. Дополнительные сведения см. в разделе Масштабирование с рабочего стола на кластер.
Определите вспомогательную функцию, которая решает систему Лоренца на разделе исследуемых параметров. Отправка промежуточных результатов клиенту MATLAB с помощью send функции на DataQueue объект.
function results = parameterSweep(first,last,sigma,rho,beta,Q) results = zeros(last-first,1); for ii = first:last-1 lorenzSystem = @(t,a) [sigma(ii)*(a(2) - a(1)); a(1)*(rho(ii) - a(3)) - a(2); a(1)*a(2) - beta*a(3)]; [t,a] = ode45(lorenzSystem,[0 100],[1 1 1]); result = a(end,3); send(Q,[ii,result]); results(ii-first+1) = result; end end
Определите другую вспомогательную функцию, которая обновляет график поверхности при поступлении новых данных.
function updatePlot(surface,data) surface.ZData(data(1)) = data(2); drawnow('limitrate'); end
afterEach | parallel.pool.DataQueue | parfeval | parpool