normcdf: speed impact by vectorization

2 次查看(过去 30 天)
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?

采纳的回答

dpb
dpb 2020-4-19
编辑:dpb 2020-4-19
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 个评论
dpb
dpb 2020-4-26
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 2020-4-28
Yes, you are right. I just tried and I am getting slight improvement with 2D array but not that dramatic

请先登录,再进行评论。

更多回答(0 个)

产品


版本

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by