Effacer les filtres
Effacer les filtres

normcdf: speed impact by vectorization

2 vues (au cours des 30 derniers jours)
Ilya Toytman
Ilya Toytman le 19 Avr 2020
Commenté : Ilya Toytman le 28 Avr 2020
Hi,
I am used to the fact that replacing a for-loop with vectorization in Matlab yields speed improvements (or at least does not degrade speed). I was trying to optimize code that relies on normcdf computation and found that vectorization actually makes things worse - with almost 2x slow-down.
Here is the code I use to verify that (simplified version for the purpose of highlighting an issue, outputs are not stored):
a = -50:0.01:50;
total_cnt = 10000;
a_mod = repmat(a, 1, total_cnt);
fprintf(1, 'Calculating single long array\n');
tic;
normcdf(a_mod, 0, 1);
toc;
fprintf(1, 'Calculating short array with for loop\n');
tic;
for k = 1 : total_cnt
normcdf(k*a, 0, 1);
end
toc;
In both instances I calculate normcdf for exactly the same number of values (~10^8) - when doing for-loop I even change the underlying values to avoid potential simply caching of calculations (not sure if Matlab does it), so that each iteration is brand new set of values. Here is an example output (2015 Macbook Pro, Matlab 2018a):
Calculating single long array
Elapsed time is 3.396627 seconds.
Calculating short array with for loop
Elapsed time is 1.450725 seconds.
It looks like I get faster computation in for-loop than with single line - is there a reason for this? I did not have time to experiment too much with it, but I tried reduce the size of a by 10x (a = -50:0.1:50) and then vectorized version became a little faster (0.35s vs 0.44s). I wonder if there is some threshold I am hitting?

Réponse acceptée

dpb
dpb le 19 Avr 2020
Modifié(e) : dpb le 19 Avr 2020
Yeah, there is... --
>> a = -50:0.01:50;
>> total_cnt = 10000;
>> a_mod = repmat(a, 1, total_cnt);
>> whos a a_mod
Name Size Bytes Class Attributes
a 1x10001 80008 double
a_mod 1x100010000 800080000 double
>>
You created a really, really long vector and disk thrashing ensued...you may have more memory and so less than here but it took 150 sec on this machine...otoh
>> a = -50:0.01:50; a=a.';
>> a_mod = repmat(a, 1, total_cnt);
>> whos a_mod
Name Size Bytes Class Attributes
a 10001x1 80008 double
a_mod 10001x10000 800080000 double
>> tic,normcdf(a_mod, 0, 1);toc
Elapsed time is 13.780391 seconds.
>>
won by about 11X over the single vector and 4X over the (probably intended) bunch of same length vectors.
Moral! Be sure you know what you're timing!!!
  3 commentaires
dpb
dpb le 26 Avr 2020
The vector is 10000X the size of the short one; you didn't store the array of 10000 columns but only the base vector. You would have to compare
a_moda=repmat(a,1,total_cnt);
a_modv=repmat(a.',1,total_cnt);
to compare that.
>> whos a*
Name Size Bytes Class Attributes
a 1x10001 80008 double
a_moda 10001x10000 800080000 double
a_modv 1x100010000 800080000 double
ans 1x1 8 double
>>
Ilya Toytman
Ilya Toytman le 28 Avr 2020
Yes, you are right. I just tried and I am getting slight improvement with 2D array but not that dramatic

Connectez-vous pour commenter.

Plus de réponses (0)

Produits


Version

R2018a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by