Распараллелить алгоритм Matlab
Я работаю над томографическим алгоритмом, используя метод SART. Я использую 2D проекции, чтобы получить объем 3D.
Моя главная проблема в том, что время вычислений очень велико.
Например, для проекций размером 88*75 пикселей моей программе нужно 5 дней.
Используя профилировщик Matlab, мы видим, что строки с умножением матрицы радона (что является тяжелым) занимают так много времени.
Вот почему я хочу распараллелить мой алгоритм, но я не очень знаком с ним.
Это часть моего алгоритма, которую я хочу распараллелить:
line which need a lot of time: Correction = mtimesx(facteur, Matrice_Radon_Transposee, 'SPEED');
for k = 1: ite % Boucle définie par le nombre d 'itérations choisi par l'
utilisateur
Soustraction = Projection2 - Projection_old;
Erreur(ligne, k) = mean(Soustraction);
Err = Erreur(ligne, k);
for z = 1: L * Nproj
for a = 1: L * L
Somme = Somme + Matrice_Radon(z, a) * Matrice_Radon(z, a);
end
facteur = landa / Somme;
Correction = mtimesx(facteur, Matrice_Radon_Transposee, 'SPEED'); % Formule de correction additive de l
'image
Correction = Correction*Soustraction;
Ik1 = Ik + Correction;
Ik=Ik1; % Stockage de l'
image corrigée dans l
'image_itération_précédente
Projection_old=Matrice_Radon*Ik; % Calcul de la projection à partir de l'
image_itération_précédente
end
pos3 = 1;
for incr2 = 1: L
for incr3 = 1: L
Ik2(incr2, incr3) = Ik1(pos3, 1); % Transformation vecteur en matrice
pos3 = pos3 + 1;
end
end
Coupe_SIRT(ligne, : , : ) = Ik2; % Stockage des coupes générées
end
fprintf('Progression : %2d/%d\n', ligne, H); % Affichage de l
'avancement du traitement
end
2 ответа
Я действительно не знаю, как векторизовать этот код..
Мне не нужно векторизовать весь код, только эти 2 строки:
Correction = mtimesx(facteur, Matrice_Radon_Transposee, 'SPEED');
Correction = Correction*Soustraction;
Так что, возможно, было бы интересно распараллелить цикл for?:
for k = 1: ite
Правильно ли написать это:
result_Projection_old = zeros(1,ite);
result_Ik = zeros(1,ite);
parfor k = 1 : ite
Somme = 0;
Projection_old = result_Projection_old(k);
Ik = result_Ik(k);
Soustraction = Projection2 - Projection_old;
for z=1:LNproj
for a=1:L_carre
Somme = Somme + Matrice_Radon(z,a)*Matrice_Radon(z,a);
end
facteur = landa/Somme;
Correction = mtimesx(facteur,Matrice_Radon_Transposee,'SPEED');
Correction = Correction*Soustraction;
Ik1 = Ik + Correction;
Ik=Ik1;
result_Ik(k) = Ik;
Projection_old=Matrice_Radon*Ik;
result_Projection_old(k) = Projection_old;
end
end
С этим кодом реконструкция не работает, вместо записи result_Ik(k) = Ik мне нужно написать Result_Ik(k+1) = Ik, чтобы на следующей итерации получить значение Ik из итерации k-1 (предыдущая итерация)
Я вижу здесь много вложенных циклов. Вы должны использовать векторизованный код вместо циклов for всякий раз, когда это возможно в MATLAB, чтобы ускорить ваш алгоритм. Также невозможно использовать вложенный парфор.
Распараллеливание возможно, когда ваши циклы независимы друг от друга (и, конечно, вам нужно установить Parallel Computing Toolbox). В этом случае использование это очень esay:
result = zeros(1,n); % preallocate result storing array
parfor i=1:n % parallel for loop
%your code here, e.g.:
result(i) = ...;
end
Пул рабочих MATALB можно настроить вручную, но также можно просто использовать parfor и позволить MATLAB автоматически обрабатывать пул (по крайней мере, в r2014a).
Обратите внимание, что распараллеливание не всегда ускоряет процесс.