2010-05-23 6 views
1

Cette question est liée à ces deux:
Introduction to vectorizing in MATLAB - any good tutorials?
filter that uses elements from two arrays at the same timevectorisation boucles dans Matlab - Problèmes de performances

basez les tutoriels que je lis, je tentais de vectoriser une procédure qui prend vraiment beaucoup de temps.

J'ai réécrite ceci:

function B = bfltGray(A,w,sigma_r) 
dim = size(A); 
B = zeros(dim); 
for i = 1:dim(1) 
    for j = 1:dim(2) 

     % Extract local region. 
     iMin = max(i-w,1); 
     iMax = min(i+w,dim(1)); 
     jMin = max(j-w,1); 
     jMax = min(j+w,dim(2)); 
     I = A(iMin:iMax,jMin:jMax); 

     % Compute Gaussian intensity weights. 
     F = exp(-0.5*(abs(I-A(i,j))/sigma_r).^2); 
     B(i,j) = sum(F(:).*I(:))/sum(F(:)); 

    end 
end 

dans ce:

function B = rngVect(A, w, sigma) 
W = 2*w+1; 
I = padarray(A, [w,w],'symmetric'); 
I = im2col(I, [W,W]); 
H = exp(-0.5*(abs(I-repmat(A(:)', size(I,1),1))/sigma).^2); 
B = reshape(sum(H.*I,1)./sum(H,1), size(A, 1), []); 


A est une matrice 512x512
w est la moitié de la taille de la fenêtre, généralement égale 5
sigma est un paramètre dans la plage [0 1] (généralement l'un de: 0,1, 0,2 ou 0,3)
Ainsi, la matrice I aurait 512x512x121 = 31719424 éléments

Mais cette version semble être aussi lent que le premier, mais en plus il utilise beaucoup de mémoire et provoque parfois des problèmes de mémoire. Je suppose que j'ai fait quelque chose de mal. Probablement une erreur de logique concernant la vectorisation. Eh bien, en fait, je ne suis pas surpris - cette méthode crée des matrices vraiment grandes et probablement les calculs sont proportionnellement plus longs.

J'ai aussi essayé de l'écrire en utilisant nlfilter (similaire à la second solution given by Jonas), mais il semble être difficile puisque j'utilise Matlab 6.5 (R13) (il n'y a aucune poignée fonction sophistiquée disponible).

Donc encore une fois, je ne demande pas de solution prête, mais pour quelques idées qui m'aideraient à résoudre ce problème dans un délai raisonnable. Peut-être que vous me pointerez ce que j'ai mal fait.

Edit:
Comme Mikhail a suggéré, les résultats du profilage sont les suivants:
65% du temps a été consacré à la ligne H= exp(...)
25% du temps a été utilisé par im2col

+0

Que dit le profileur? Quelle ligne prend le plus de temps pour calculer? – Mikhail

+0

Mikhail, j'ai mis à jour ma question. – Gacek

Répondre

1

Quelle sont I et H (c'est-à-dire numel(I)*8 octets)? Si vous démarrez la pagination, les performances de votre deuxième solution vont être très affectées.

Pour vérifier si vous avez vraiment un problème dû à des réseaux trop grands, vous pouvez essayer de mesurer la vitesse du calcul en utilisant tic et toc pour les tableaux A de taille croissante. Si le temps d'exécution augmente plus vite que le carré de la taille de A, ou si le temps d'exécution saute à une taille de A, vous pouvez essayer de diviser le I rembourré en un certain nombre de sous-matrices et effectuer les calculs comme cela.

Sinon, je ne vois pas d'endroits où vous pourriez perdre beaucoup de temps.Eh bien, peut-être que vous pourriez sauter le Reshape, en remplaçant B avec A dans votre fonction (sauve un peu de mémoire, ainsi), et l'écriture A(:) = sum(H.*I,1)./sum(H,1);

Vous pouvez également regarder dans la mise à niveau vers une version plus récente de Matlab - ils ont travaillé dur pour améliorer la performance.

+0

Jonas, j'ai mis à jour ma question. Comme je l'ai écrit, les matrices générées deviennent vraiment importantes et j'ai peur que ma solution ne soit pas la meilleure pour ce genre de problème. – Gacek

+0

Oh, je n'ai vu ça que maintenant. J'ai également mis à jour ma réponse sur la façon dont vous pouvez savoir s'il est possible d'accélérer les calculs. – Jonas

+0

La matrice 'I' ayant 31 millions d'éléments est grande, mais pas énorme ... Je voudrais seconder l'appel pour voir si les petites tailles de j'ai beaucoup de meilleures performances. Si c'est le cas, il se peut que Matlab ait beaucoup de mal à trouver un morceau continu de 64 Mo de mémoire. Est-ce un vieil ordinateur? Essayez de redémarrer immédiatement avant d'exécuter le programme, la mémoire est moins fragmentée au démarrage. Ou obtenir plus de RAM? – rescdsk