ile parfor
dotyczy trzy następujące instrukcje można uznać za równoważne:
1) iteracji parfor
pętli musi być niezależne.
2) Brak iteracji pętli parfor
może zależeć od wyniku jakiejkolwiek innej iteracji.
3) iteracje w parfor
pętli musi być wykonywane w dowolnej kolejności (od @Oli)
Jak oświadczenia te porównania do zwykłej pętli? W typowej pętli od 1 do 8, czwarta iteracja, na przykład, może zależeć od iteracji 1, 2 i 3, ponieważ oprogramowanie może być pewne, że te iteracje już wystąpiły przed osiągnięciem liczby iteracyjnej 4. NIE zależą od iteracji 5, 6, 7 i 8, ponieważ oprogramowanie może być pewne, że te powtórzenia nie wystąpią.
W pętli parfor
, jak stwierdza @Ali, pętle mogą występować w dowolnej kolejności. Mogą one występować w następującej kolejności, na przykład 7 3 4 1 2 5 8 6. Lub dowolnej permutacji tych 8 liczb. To implikuje coś bardzo ważnego: Nie można się dowiedzieć przed faktem, która iteracja wystąpi jako pierwsza. Aby to zobaczyć, po prostu przetrzyj fprintf('Up to iteration %d of %d\n', t, T)
wewnątrz pętli parfor
, gdzie t
jest pętlą dolną, a T
jest górną granicą pętli.
Powyższe stwierdzenie natychmiast implikuje następujący wniosek: Ponieważ jakakolwiek iteracja może wystąpić najpierw, ważne jest, aby żadna iteracja nie zależała od wyniku jakiejkolwiek innej iteracji. Będę zawrzeć odpowiedź z kilkoma przykładami:
X = ones(8, 8)
parfor n = 1:8
X(:,n) = X(:,n) .* (3 * ones(8,1));
end
W tym przykładzie (3 * ones(8,1))
wyraźnie nie zależy od jakiejkolwiek innej iteracji - jest stała w stosunku do licznika pętli. Podobnie X(:, n)
nie zależy od żadnej innej iteracji niż nth. EDYCJA: Poprzednio używałem randn
w powyższym przykładzie - zobacz dyskusję w komentarzach dostarczonych przez @AndrewJanke, dlaczego to był zły pomysł. Co z tą sytuacją:
X = ones(8, 8);
parfor n = 1:8
X(:,n) = X(:,n) + (n + 1);
end
Jest to również całkowicie prawidłowe. Chociaż w wyrażeniu występuje wyrażenie n + 1
, nie jest to to samo, co w przypadku numeru iteracji n + 1
. Raczej jest to po prostu przypisanie wartości liczby całkowitej bieżącego numeru iteracji, plus 1, do X
.
Wreszcie, należy rozważyć:
X = ones(8, 1);
parfor n = 2:8
X(n, 1) = X(n-1, 1) + 1;
end
Byłoby idealnie ważne w zwykłej pętli, ponieważ liczba iteracji n-1
będzie zawsze występować przed iteracji n
(zakładając mamy pętlę do przodu). Ale w pętli parfor
spowoduje to błąd, ponieważ numer iteracji n
może wystąpić przed numerem iteracji n-1
.Lingo Matlab używa do opisania problemu, który nazywa się "krojeniem". Wyobraź sobie, że X
ma zostać pocięte przez iteracje pętli. Następnie w n-tej iteracji możesz tylko odwołać się do n-tego wycinka X
.
Ostatni punkt, jeśli kiedykolwiek mam wątpliwości co do pętli parfor
, przeczytałem rozdział w dokumentacji zatytułowany: "Równolegle dla pętli w Matlabie - omówienie" (przepraszam, nie mogę znaleźć odpowiedniej strony - nietypowe dla Matlaba dokumentacja) Opisuje wszystkie możliwe zmienne klasyfikacje wewnątrz pętli, a ograniczenia nakładają pętle na każdą klasyfikację. To, o czym mówiłem w tej odpowiedzi, to tak naprawdę tylko wierzchołek góry lodowej. Na przykład instrukcje takie jak n = n + 1
są również nieprawidłowe w pętli parfor
, ponieważ n
jest zmienną pętli, a przypisania do zmiennej pętli są niedozwolone.
Matlab usuwa błąd, jeśli nie jest prawidłową pętlą równoległą. Musisz po prostu uruchomić to w programie Matlab, a otrzymasz odpowiedź natychmiast. – Oli
Ten cytat z dokumentów wydaje się wskazywać, że Matlab nie zawsze ostrzega: "Uwaga Z powodu niezależności zamówienia iteracyjnego wykonanie parfor nie gwarantuje wyników deterministycznych." – Andreas
To oznacza, że można wykonać iterację w dowolnej kolejności. To nie ma wpływu na twoją sprawę. – Oli