2014-09-17 2 views
3

병렬 처리를 반복하고 조건이 충족되면 변수를 변경합니다.MATLAB에서 parfor를 사용할 때 경쟁 조건 피하기

trials = 100; 
greatest_so_far = 0; 
best_result = 0; 

for trial_i = 1:trials 
    [amount, result] = do_work(); 

    if amount > greatest_so_far 
     greatest_so_far = amount; 
     best_result = result; 
    end 
end 

내가 parfor에 의해 for을 교체하고 싶다면, 우리가 greatest_so_far을 교체할지 여부를 검사 할 때 조건이 경주되지 않도록 할 수있는 방법 : 모두 확신 슈퍼 관용적 코드는 백 번을 썼다? 이 변수를 수표 바깥에 고정시키는 방법이 있습니까? 아마도 :

trials = 100; 
greatest_so_far = 0; 
best_result = 0; 

parfor trial_i = 1:trials 
    [amount, result] = do_work(); 

    somehow_lock(greatest_so_far); 
    if amount > greatest_so_far 
     greatest_so_far = amount; 
     best_result = result; 
    end 
    somehow_unlock(greatest_so_far); 
end 
+0

이 링크는 matlab에 뮤텍스를 사용할 수있는 것처럼 보입니다. 나는 그것에 대한 경험이 없지만 이것이 당신이 원하는 것이라고 생각합니다. http://www.mathworks.com/matlabcentral/answers/22180-timers-and-thread-safety – KDecker

+0

감사합니다 BumSkeeter, 내가 뭘 할 수 있는지 보자. – rhombidodecahedron

+1

+1 잘 쓰여진 질문 –

답변

2

기울이기 대답. 문제를 정확히 해결하지는 못하지만 문제를 피하는 데 도움이 될 수 있습니다.

do_work()의 출력을 일부 벡터에 저장할 수있는 여유가 있다면이 기능에서만 parfor을 실행하고 결과를 저장 한 다음 루프의 바깥 쪽에서 채점하십시오. :

amount = zeros(trials , 1) ; 
result = zeros(trials , 1) ; 

parfor trial_i = 1:trials 
    [amount(i), result(i)] = do_work(); 
end 

[ greatest_of_all , greatest_index ] = max(amount) ; 
best_result = result(greatest_index) ; 

편집/코멘트 : (이 질문의 의견에 그것을 넣어 싶어하지만 죄송합니다, 너무 오래했다).
저는 .net에 익숙하며 잠금/잠금 해제 요청을 완전히 이해하고 있습니다. 나 자신은 매우 긴 parfor 루프 진행 표시기를 구현하려고 많은 시도를했는데 ... 아무 소용이 없습니다.

나는 제대로 matlab에 classification of variable, 당신은 greatest_so_far (greatest_so_far=amount에) 할당하는 것이 단순한 사실 매트랩에 따라서 사용할 수없는 모든 루프 반복의 시작 (클리어하고 다시 초기화됩니다 일시 변수로 취급 할을 이해한다면 당신의 목적).

쉽게 잠김 변수은 지금 당장 구현할 수있는 개념이 아닐 수 있습니다. 일부 복잡한 이벤트 나 파일 쓰기/검사가 트릭을 할 수도 있지만 타이밍이 크게 어려워 질까 걱정됩니다. 각 반복이 실행하는 데 오랜 시간이 걸리면 오버 헤드가 그럴 가치가 있지만 parfoor을 사용하여 짧은 실행 반복 횟수를 줄이면 복잡한 솔루션이 도움이되는 것보다 느려집니다.

이 스택 교환 질문을 살펴보면 다음과 같은 흥미로운 점을 발견 할 수 있습니다. Semaphores and locks in MATLAB

+0

나는 또한이 해결책을 생각했다. 그럼에도 불구하고 모든 결과를 저장해야하기 때문에 바람직하지 않지만 그럼에도 불구하고 트릭을 수행합니다. 아무도 따라 오지 않으면이 대답을 받아 들일 것입니다. – rhombidodecahedron

+1

매우 명쾌하게 "그것은 당신의 문제를 정확하게 해결하지 못했지만 그것을 피하는 데 도움이 될 것입니다"라고 이미 +1했는데 :-) –

2

Hoki의 해결책은 문제를 해결하는 올바른 방법입니다. 그러나 루프 반복이 서로에 달려있을 때 경쟁 조건에 대해 질문하고 방지하면 spmd and the various lab* functions을 조사 할 수 있습니다.

1

이렇게하려면 SPMD를 사용해야합니다. SPMD를 사용하면 작업자간에 통신 할 수 있습니다. 다음과 같은 것 :

bestResult = -Inf; 
bestIndex = NaN; 
N = 97; 
spmd 
    % we need to round up the loop range to ensure that each 
    % worker executes the same number of iterations 
    loopRange = numlabs * ceil(N/numlabs); 
    for idx = 1:numlabs:loopRange 
    if idx <= N 
     local_result = rand(); % obviously replace this with your actual function 
    else 
     local_result = -Inf; 
    end 
    % Work out which index has the best result - use a really simple approach 
    % by concatenating all the results this time from each worker 
    % allResultsThisTime will be 2-by-numlabs where the first row is all the 
    % the results this time, and the second row is all the values of idx from this time 
    allResultsThisTime = gcat([local_result; idx]); 
    % The best result this time - consider the first row 
    [bestResultThisTime, labOfBestResult] = max(allResultsThisTime(1, :)); 
    if bestResultThisTime > bestResult 
     bestResult = bestResultThisTime; 
     bestIndex = allResultsThisTime(2, labOfBestResult); 
    end 
    end 
end 
disp(bestResult{1}) 
disp(bestIndex{1})