Проблема здесь заключается в неправильной индексации секционированного массива. parfor
циклы запускаются асинхронно , что означает, что порядок выполнения каждой итерации является случайным. Из документации :
Сотрудники MATLAB оценивают итерации не в определенном порядке и независимо друг от друга. Поскольку каждая итерация независима, нет никакой гарантии, что итерации синхронизированы каким-либо образом, и в этом нет необходимости.
Вы можете легко проверить приведенное выше утверждение, набрав в командной строке следующее:
parfor i=1:100
i
end
Вы увидите, что порядок произвольный. Следовательно, если вы разделите параллельное задание между разными работниками, один работник не сможет определить, завершена ли другая итерация или нет. Следовательно, индексирование вашей переменной не может зависеть от прошлых / будущих значений итератора.
Позвольте мне продемонстрировать это на простом примере. Рассмотрим ряд Фибоначчи 1,1,2,3,5,8,...
. Вы можете легко сгенерировать первые 10 членов серии (в наивном цикле for
) как:
f=zeros(1,10);
f(1:2)=1;
for i=3:10
f(i)=f(i-1)+f(i-2);
end
Теперь давайте сделаем то же самое с циклом parfor
.
f=zeros(1,10);
f(1:2)=1;
parfor i=3:10
f(i)=f(i-1)+f(i-2);
end
* * ??? тысяча двадцать восемь Ошибка: переменная f в parfor не может быть классифицирована.
См. Параллельные циклы в MATLAB, "Обзор"
Но почему это дает ошибку?
Я показал, что итерации выполняются в произвольном порядке. Допустим, рабочий получает индекс цикла i=7
и выражение f(i)=f(i-1)+f(i-2);
. Теперь предполагается выполнить выражение и вернуть результаты в главный узел. Теперь итерация i=6
закончена? Надежно ли хранится значение в f(6)
? Как насчет f(5)
? Ты видишь, к чему я клоню? Предположим, что f(5)
и f(6)
не выполнены, и вы неправильно вычислите, что седьмой член в ряду Фибоначчи равен 0!
Поскольку MATLAB не может определить, можно ли гарантировать, что ваш расчет будет гарантированно выполняться правильно и каждый раз воспроизводить один и тот же результат, такие неоднозначные назначения явно запрещены.