Выполните функцию асинхронно на параллельном рабочем пула
запрашивает асинхронное выполнение функционального F
= parfeval(p
,fcn
,numout
,in1,in2,...
)fcn
на рабочем, содержавшемся в параллельном пуле p
, ожидание numout
выходные аргументы и предоставляющий как входные параметры in1,in2,...
. Асинхронная оценка fcn
не делает блока MATLAB. F
параллель. Объект FevalFuture, из которого могут быть получены результаты, когда рабочий завершил оценку fcn
. Оценка fcn
всегда доходы, если вы явным образом не отменяете выполнение путем вызова cancel(F)
. Чтобы запросить несколько функциональных оценок, необходимо вызвать parfeval
многократно. (Однако parfevalOnAll
может запустить ту же функцию на всех рабочих.)
запрашивает асинхронное выполнение на текущем параллельном пуле. Если никакой пул не существует, это запускает новый параллельный пул, если ваши параллельные настройки не отключают автоматическое создание пулов.F
= parfeval(fcn
,numout
,in1,in2,...
)
parfeval
В этом примере показано, как выполнить параллельную развертку параметра с parfeval
и передайте результаты обратно во время расчетов с DataQueue
объект. parfeval
не делает блока MATLAB, таким образом, можно продолжить работать, в то время как расчеты происходят.
Пример выполняет развертку параметра в системе Лоренца обыкновенных дифференциальных уравнений на параметрах и , и показывает хаотическую природу этой системы.
Создайте сетку параметра
Задайте область значений параметров, которые вы хотите исследовать в развертке параметра.
gridSize = 40; sigma = linspace(5, 45, gridSize); rho = linspace(50, 100, gridSize); beta = 8/3;
Создайте 2D сетку параметров при помощи meshgrid
функция.
[rho,sigma] = meshgrid(rho,sigma);
Создайте объект фигуры и установите 'Visible'
к true
так, чтобы это открылось в новом окне, за пределами live скрипта. Чтобы визуализировать результаты развертки параметра, создайте объемную поверхностную диаграмму. Обратите внимание на то, что инициализация 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
Используйте parfeval
запрашивать асинхронное выполнение функции на рабочем.
Например, отправьте один запрос к параллельному пулу. Получите выходные параметры при помощи fetchOutputs
.
f = parfeval(@magic,1,10); value = fetchOutputs(f);
Можно также представить вектор нескольких будущих запросов в for
- цикл и собирает результаты, когда они становятся доступными. Для КПД предварительно выделите массив будущих объектов прежде.
f(1:10) = parallel.FevalFuture; for idx = 1:10 f(idx) = parfeval(@magic,1,idx); end
Получите отдельные будущие выходные параметры, когда они становятся доступными при помощи fetchNext
.
magicResults = cell(1,10); for idx = 1:10 [completedIdx,value] = fetchNext(f); magicResults{completedIdx} = value; fprintf('Got result with index: %d.\n', completedIdx); end
afterEach
и afterAll
Можно выполнить асинхронные расчеты на рабочих, использующих parfeval
и оставьте пользовательский интерфейс быстро реагирующим. Используйте afterEach
обновить пользовательский интерфейс, когда промежуточные расчеты готовы. Используйте afterAll
обновить пользовательский интерфейс, когда все расчеты готовы.
Создайте простой пользовательский интерфейс с помощью waitbar
.
h = waitbar(0, 'Waiting...');
Используйте parfeval
выполнить длительные расчеты в рабочих, например, собственных значениях случайных матриц. Расчеты происходят асинхронно и обновления пользовательского интерфейса во время расчета. С настройками по умолчанию, parfeval
создает parpool
автоматически, если нет того, уже созданного.
for idx = 1:100 f(idx) = parfeval(@(n) real(eig(randn(n))), 1, 5e2); end
Вычислите самое большое значение в каждом из расчетов, когда они станут готовым использованием afterEach
. Обновите пропорцию законченных фьючерсов в waitbar, когда каждый из них завершит использование afterEach
.
maxFuture = afterEach(f, @max, 1);
updateWaitbarFuture = afterEach(f, @(~) waitbar(sum(strcmp('finished', {f.State}))/numel(f), h), 1);
Закройте waitbar, когда все расчеты будут сделаны. Используйте afterAll
на updateWaitbarFuture
продолжаться автоматически операцией закрытия. afterAll
получает указатель фигуры из updateWaitbarFuture
и выполняет его функцию на нем.
closeWaitbarFuture = afterAll(updateWaitbarFuture, @(h) delete(h), 0);
Покажите гистограмму после того, как все максимальные значения будут вычислены. Используйте afterAll
на maxFuture
продолжать операцию автоматически. afterAll
получает максимальные значения из maxFuture
и вызовы histogram
на них.
showsHistogramFuture = afterAll(maxFuture, @histogram, 0);
p
— Параллельный пулparallel.Pool
объектПараллельный пул рабочих, заданных как parallel.Pool
объект. Можно создать параллельный пул при помощи parpool
функция.
Типы данных: parallel.Pool
fcn
— Функция, чтобы выполнитьсяФункция, чтобы выполниться на рабочем, определенном функцией указателе.
Пример: fcn = @sum
Типы данных: function_handle
numout
— Количество выходных аргументовКоличество выходных аргументов, которые ожидаются от fcn
.
Типы данных: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
in1,in2,...
Аргументы функцииАргументы функции, чтобы передать fcn
, заданный как список, разделенный запятыми переменных или выражений.
F
— Будущееparallel.FevalFuture
Будущий объект, возвращенный как parallel.FevalFuture
, это представляет выполнение fcn
на параллельном рабочем и содержит его результаты. Используйте fetchOutputs
или fetchNext
собрать результаты.
afterAll
| afterEach
| cancel
| fetchNext
| fetchOutputs
| isequal
| параллель. FevalFuture | parallel.pool.Constant
| parfevalOnAll
| parpool
| ticBytes
| tocBytes
| wait
У вас есть модифицированная версия этого примера. Вы хотите открыть этот пример со своими редактированиями?
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.