2 votes

vitesse de calcul dans une boucle for

J'ai écrit une petite boucle dans matlab pour générer une matrice aléatoire NxN. La boucle est

tic
for i=1:10000
    u=rand(1,10000);
    tau(i,:)=d.*(u(1,:)-0.5);
end
toc

J'ai d'abord essayé la routine de la boucle une seule fois,

    u=rand(1,10000);
    tau=d.*(u(1,:)-0.5);

ce qui m'a donné tau en 0,000169 seconde. J'ai supposé que la boucle prendrait alors environ 1,69s. Ce n'est pas le cas, il a fallu 555,018280 secondes avec les ventilateurs qui s'affolent.

Y a-t-il
a) une raison pour laquelle la vitesse n'est pas linéairement liée au nombre d'itérations ?
b) une raison pour laquelle il faut donc beaucoup plus de temps pour faire la routine plusieurs fois
c) un moyen d'accélérer ce processus (j'aimerais en fait générer des matrices plus grandes), par exemple une meilleure boucle ou un moyen de me donner, disons, une matrice 1'000'000x1'000'000 du même type ?

7voto

Acorbe Points 7541

Vous devez tout d'abord pré-allouer votre matrice tau , c'est-à-dire

  tau = zeros(10000,10000);

sinon matlab le réallouera continuellement dans les régions où il y a suffisamment de mémoire libre (=> trouver une région avec suffisamment d'espace libre + copie papier).

En général, vous obtiendrez de meilleures performances en vectorisant l'ensemble du processus :

 u=rand(10000,10000);
 tau=d.*(u-0.5);

EDIT : Surtout, écoutez les conseils avisés de Rody dans le commentaire ci-dessous. (En tout cas, je supposer que rand(a,b) fonctionnerait un peu plus vite que a exécutions en série de rand(1,b) ).

0voto

Patricia Shanahan Points 11270

Une possibilité évidente est la quantité d'accès à la mémoire. La mémoire de la boucle de test aurait pu être entièrement en cache, mais la mémoire écrite par la boucle complète nécessitait beaucoup d'accès à la mémoire principale.

Il s'agit d'une hypothèse vérifiable : Le temps d'écrire toute la matrice, sans faire l'arithmétique.

Si je comprends bien l'indexation de Matlab, il serait peut-être plus rapide d'inverser les dimensions, de manière à écrire des blocs qui se trouvent dans la même colonne, plutôt que dans la même ligne. Convertir u en un vecteur colonne en dehors de la boucle peut également aider. En général, l'accès aux grandes matrices doit se faire, dans la mesure du possible, dans l'ordre de la mémoire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X