Main Content

이 페이지의 최신 내용은 아직 번역되지 않았습니다. 최신 내용은 영문으로 볼 수 있습니다.

parfeval

병렬 풀 워커에서 비동기식으로 함수 실행

설명

예제

F = parfeval(p,fcn,numout,in1,in2,...)는 병렬 풀 p에 포함된 워커에서 함수 fcn을 비동기식으로 실행하도록 요청합니다. numout은 기대하는 출력 인수 개수를 나타내며 in1,in2,...는 함수에 제공되는 입력 인수입니다. fcn의 비동기 실행은 MATLAB을 차단하지 않습니다. Fparallel.FevalFuture 객체이며.워커가 fcn의 실행을 완료하면 이 객체에서 결과를 얻을 수 있습니다. fcn의 실행은 cancel(F)를 호출하여 실행을 명시적으로 취소하지 않는 한 항상 진행됩니다. 함수의 실행을 여러 번 요청하려면 parfeval을 여러 번 호출해야 합니다. (참고로, parfevalOnAll은 모든 워커에서 동일한 함수를 실행할 수 있습니다.)

예제

F = parfeval(fcn,numout,in1,in2,...)는 현재 병렬 풀에서 비동기 실행을 요청합니다. 병렬 기본 설정에 자동 풀 생성이 비활성화되어 있지 않다면 풀이 없는 경우 새 병렬 풀이 시작됩니다.

예제

모두 축소

parfeval을 사용하여 워커에서 비동기식 함수 실행을 요청할 수 있습니다.

예를 들어, 병렬 풀에 단일 요청을 제출해 보겠습니다. fetchOutputs를 사용하여 출력값을 가져옵니다.

f = parfeval(@magic,1,10);
value = fetchOutputs(f);

또한 for 루프 안에 여러 future 요청으로 구성된 벡터를 제출하고 결과가 나오는 대로 수집할 수 있습니다. 효율성을 위해서 future 객체로 구성된 배열을 미리 사전할당합니다.

f(1:10) = parallel.FevalFuture;
for idx = 1:10
f(idx) = parfeval(@magic,1,idx);
end

fetchNext를 사용하여 개별 future 출력값이 나오는 대로 가져옵니다.

magicResults = cell(1,10);
for idx = 1:10
[completedIdx,value] = fetchNext(f);
magicResults{completedIdx} = value;
fprintf('Got result with index: %d.\n', completedIdx);
end

이 예제에서는 parfeval을 사용하여 병렬 파라미터 스윕을 수행하고 DataQueue 객체를 사용하여 계산 중에 결과를 다시 보내는 방법을 보여줍니다. parfeval은 MATLAB을 차단하지 않으므로 계산이 수행되는 동안 계속해서 작업할 수 있습니다.

이 예제는 로렌츠 연립상미분방정식에서 파라미터 σρ에 대한 파라미터 스윕을 수행하고 이 연립방정식의 혼돈적인 성질을 보여줍니다.

ddtx=σ(y-z)ddty=x(ρ-z)-yddtz=xy-βx

파라미터 그리드 만들기

파라미터 스윕에서 탐색할 파라미터의 범위를 정의합니다.

gridSize = 40;
sigma = linspace(5, 45, gridSize);
rho = linspace(50, 100, gridSize);
beta = 8/3;

meshgrid 함수를 사용하여 파라미터의 2차원 그리드를 만듭니다.

[rho,sigma] = meshgrid(rho,sigma);

figure 객체를 만들고 'Visible'true로 설정하면 라이브 스크립트 밖의 새 창에서 열립니다. 파라미터 스윕의 결과를 시각화하려면 곡면 플롯을 만드십시오. NaN을 사용하여 곡면의 Z 구성요소를 초기화하면 빈 플롯이 만들어집니다.

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

최상의 성능을 구현하려면 다음과 같은 파티션 크기로 분할하십시오.

  • 파티션을 나누는데 드는 오버헤드에 비해 계산 시간이 더 길 정도로 충분히 큰 크기.

  • 모든 워커에서 계산을 수행할 수 있을 정도로 충분히 작은 크기.

병렬 워커에서 함수 실행을 표현하고 결과를 유지하려면 future 객체를 사용하십시오.

f(1:numel(partitions)-1) = parallel.FevalFuture;

parfeval 함수를 사용하여 병렬 워커에 계산을 분담할 수 있습니다. parameterSweep은 탐색할 파라미터의 파티션에 대해 로렌츠 연립방정식을 푸는 아래 스크립트의 마지막에 정의된 헬퍼 함수입니다. 출력 인수가 하나이므로 parfeval에서 출력값 개수로 1을 지정해야 합니다.

for ii = 1:numel(partitions)-1
    f(ii) = parfeval(@parameterSweep,1,partitions(ii),partitions(ii+1),sigma,rho,beta,Q);
end

parfeval은 MATLAB을 차단하지 않으므로 계산이 수행되는 동안 계속해서 작업할 수 있습니다. 워커는 병렬로 계산하며 중간 결과가 나오는 대로 DataQueue를 통해 전송합니다.

parfeval이 완료될 때까지 MATLAB을 차단하려면 future 객체에 wait 함수를 사용하십시오. wait 함수는 후속 코드가 parfeval 계산의 완료 여부에 종속되는 경우에 유용하게 사용할 수 있습니다.

wait(f);

parfeval 계산을 마치면 wait가 완료된 후에 나머지 코드를 실행할 수 있습니다. 예를 들어, 결과 곡면의 등고선을 플로팅해 보겠습니다. fetchOutputs 함수를 사용하여 future 객체에 저장된 결과를 가져오십시오.

results = reshape(fetchOutputs(f),gridSize,[]);
contourf(rho,sigma,results)
xlabel('\rho','Interpreter','Tex')
ylabel('\sigma','Interpreter','Tex')

파라미터 스윕에 계산 리소스가 더 필요하고 클러스터에 액세스할 수 있는 경우 parfeval 계산을 확장할 수 있습니다. 자세한 내용은 Scale Up from Desktop to Cluster 항목을 참조하십시오.

헬퍼 함수 정의하기

탐색할 파라미터의 파티션에 대해 로렌츠 연립방정식을 푸는 헬퍼 함수를 정의합니다. DataQueue 객체의 send 함수를 사용하여 중간 결과를 MATLAB 클라이언트로 전송합니다.

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을 사용하여 워커에서 비동기 계산을 수행하여 반응이 빠른 사용자 인터페이스를 만들 수 있습니다. 중간 계산이 준비되면 afterEach를 사용하여 사용자 인터페이스를 업데이트합니다. 모든 계산이 준비되면 afterAll을 사용하여 사용자 인터페이스를 업데이트합니다.

waitbar를 사용하여 간단한 사용자 인터페이스를 만듭니다.

h = waitbar(0, 'Waiting...');

parfeval을 사용하여 시간이 많이 소용되는 계산(예: 확률 행렬에서 고유값을 구하는 계산)을 워커에서 수행합니다. 계산은 비동기식으로 수행되고 사용자 인터페이스는 계산 수행 중에 업데이트됩니다. 디폴트 기본 설정에서 parfevalparpool이 아직 하나도 만들어지지 않은 경우 자동으로 만듭니다.

for idx = 1:100
  f(idx) = parfeval(@(n) real(eig(randn(n))), 1, 5e2); 
end

계산이 준비되면 afterEach를 사용하여 각 계산에서 가장 큰 값을 계산합니다. 각 계산이 완료되면 afterEach를 사용하여 waitbar에서 완료된 future 객체의 비율을 업데이트합니다.

maxFuture = afterEach(f, @max, 1);
updateWaitbarFuture = afterEach(f, @(~) waitbar(sum(strcmp('finished', {f.State}))/numel(f), h), 1);

모든 계산이 완료되면 waitbar를 닫습니다. updateWaitbarFutureafterAll을 사용하여 자동으로 닫기 연산을 계속 수행합니다. afterAllupdateWaitbarFuture에서 Figure 핸들을 받아 해당 함수를 실행합니다.

closeWaitbarFuture = afterAll(updateWaitbarFuture, @(h) delete(h), 0);

모든 최댓값 계산이 완료된 후 히스토그램을 표시합니다. maxFutureafterAll을 사용하여 자동으로 연산을 계속 수행합니다. afterAllmaxFuture에서 최댓값을 받아 이 최댓값에 대해 histogram을 호출합니다.

showsHistogramFuture = afterAll(maxFuture, @histogram, 0);

입력 인수

모두 축소

워커의 병렬 풀로, parallel.Pool 객체로 지정됩니다. parpool 함수를 사용하여 병렬 풀을 만들 수 있습니다.

데이터형: parallel.Pool

워커에서 실행할 함수로, 함수 핸들로 지정됩니다.

예: fcn = @sum

데이터형: function_handle

fcn에서 예상되는 출력 인수 개수입니다.

데이터형: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

fcn에 전달할 함수 인수로, 변수 또는 표현식이 쉼표로 구분된 목록으로 지정됩니다.

출력 인수

모두 축소

Future 객체로, 병렬 워커에서의 fcn 실행을 나타내고 그 결과를 유지하는 parallel.FevalFuture로 반환됩니다. 결과를 수집하려면 fetchOutputs 또는 fetchNext를 사용하십시오.

R2013b에 개발됨