Как адаптировать мой цикл, чтобы он работал с парфором Matlab?

Я совсем новичок в Матлабе. Я использую цикл parfor для выполнения чрезвычайно трудоемкой задачи. См. фрагмент ниже. Однако я получил информацию об ошибке от Matlab. Кто-нибудь может помочь? Я прочитал документ о парфоре, но не вижу, что делать...

Спасибо.

The parfor loop cannot run due to the way variable "M" is used

The parfor loop cannot run due to the way variable "T" is used


Explanation 
MATLAB runs loops in parfor functions by dividing the loop iterations into groups, and then sending them to MATLAB workers where they run in parallel. For MATLAB to do this in a repeatable, reliable manner, it must be able to classify all the variables used in the loop. The code uses the indicated variable in a way that is incompatible with classification.




 parfor i=1:size(x,1)

    if (ind(index(i)) == Index1)
        para=lsqcurvefit(F, [M(index(i)) T(index(i))], t, SS(ind(index(i)):end,i), [0 0], [MaxiM(index(i)) maxT],options);
    elseif  (ind(index(i)) == Index2) 
        para=lsqcurvefit(F, [M(index(i)) T(index(i))], t2, SS(ind(index(i)):end,i), [0 0], [MaxiM(index(i)) maxT],options);
    end

end

person zell    schedule 16.02.2013    source источник
comment
Я предполагаю, что para является результатом ваших вычислений. Если вы запускаете свой код в последовательном режиме, para будет перезаписываться на каждом шаге, поэтому я не понимаю, как вы можете запускать его параллельно. Как выглядит ваш последовательный цикл?   -  person Kleist    schedule 16.02.2013
comment
@Kleist: к счастью, это легко исправить, написав, например. para{i}=...   -  person Jonas    schedule 16.02.2013


Ответы (1)


Вы должны реорганизовать M и T, чтобы использовать их в параллельном цикле. Это должно работать:

M = M(index);
T = T(index);
parfor i=1:size(x,1)
    if (ind(index(i)) == Index1)
        para = lsqcurvefit(F, [M(i) T(i)], t, SS(ind(index(i)):end,i), ...
                           [0 0], [MaxiM(index(i)) maxT], options);
    elseif (ind(index(i)) == Index2) 
        para = lsqcurvefit(F, [M(i) T(i)], t2, SS(ind(index(i)):end,i), ...
                           [0 0], [MaxiM(index(i)) maxT], options);
    end
end

Однако, если вам нужен возврат функции lsqcurvefit - тогда я соглашусь с комментарием Kleist, что ваш код бессмысленен.

ОБНОВЛЕНИЕ:

Вы можете попробовать сделать аналогичные перестановки для дальнейшего повышения производительности:

M = M(index);
T = T(index);
ind = ind(index);
MaxiM = MaxiM(index);
parfor i=1:size(x,1)
    if (ind(i) == Index1)
        para = lsqcurvefit(F, [M(i) T(i)], t, SS(ind(i):end,i), ...
                           [0 0], [MaxiM(i) maxT], options);
    elseif (ind(i) == Index2) 
        para = lsqcurvefit(F, [M(i) T(i)], t2, SS(ind(i):end,i), ...
                           [0 0], [MaxiM(i) maxT], options);
    end
end
person miy    schedule 16.02.2013
comment
Привет, это работает. Однако прирост производительности составляет всего 30%. Это нормально? - person zell; 18.02.2013
comment
@zell: 30% приходится на 2 ядра? В общем, вы должны использовать массивы в цикле parfor таким образом, чтобы их можно было разделить между рабочими процессами. - person miy; 19.02.2013
comment
@zell: последняя версия кода, вероятно, может быть улучшена (с точки зрения производительности) путем переупорядочения массива SS. - person miy; 19.02.2013