MATLAB Answers

Why stock DOT function is suboptimally implemented

조회 수: 2(최근 30일)
Bruno Luong
Bruno Luong 2020년 10월 20일
댓글: Jan 2021년 7월 28일
Followup the discussion in
and
and do so tic/toc and I think the option selected by TMW (R2020b) is suboptimal in term of speed for complex data as show as this benchmark that one can speed up almost 10 times (!):
z=randn(1,1e7)+1i*randn(1,1e7);
tic
p1=dot(z,z);
toc % Elapsed time is 0.162930 seconds.
tic
p2 = sum(conj(z).*z);
toc % Elapsed time is 0.092252 seconds.
tic
p3=z(:)'*z(:); % (:) copy data ?
toc % Elapsed time is 0.100122 seconds.
tic
zc=z(:); % (:) copy data ?
p4=zc'*zc;
toc % Elapsed time is 0.053257 seconds.
tic
zr=reshape(z,[],1); % reshape does not?
p5=zr'*zr;
toc % Elapsed time is 0.016140 seconds.
Any comment would be welcome.
Just to have a formal question: what is the reason of TMW choice?
  댓글 수: 2
Jan
Jan 2021년 7월 28일
Wow, 0.007 is fast.

댓글을 달려면 로그인하십시오.

답변(2개)

Jan
Jan 2020년 10월 20일
편집: Jan 2020년 10월 20일
Just a comment: Under Matlab 2018b, Core i5-3320M CPU @ 2.60GHz:
Elapsed time is 0.249669 seconds. dot(z,z)
Elapsed time is 0.168906 seconds. sum(conj(z).*z)
Elapsed time is 0.204284 seconds. z(:)'*z(:)
Elapsed time is 0.114597 seconds. zc=z(:); p4=zc'*zc
Elapsed time is 0.018371 seconds. zr=reshape(z,[],1); p5=zr'*zr
When I copy the code into a function and repeat the calls 5 times in a FOR loop:
Elapsed time is 0.865391 seconds.
Elapsed time is 0.844665 seconds.
Elapsed time is 1.021389 seconds.
Elapsed time is 0.484573 seconds.
Elapsed time is 0.047871 seconds.

Jan
Jan 2021년 7월 28일
In dot.m we find a test for integer types, checks by isvector, comparison of lengths, both vectors are shaped by (:) and after a test with isreal(), either a'*b or sum(conj(a).*b) is called.
Your measurement
% Elapsed time is 0.167038 seconds. % p1 = dot(z,z)
% Elapsed time is 0.088275 seconds. % p2 = sum(conj(z).*z)
means, that the tests are expensive and the two (:) operations also, because they create deep data copies in modern Matlab versions for complex data:
a = rand(1,100) + 1i * rand(1,100);
ShowDataPointer(a)
pr = 7fe94d7f3d20
b = a(:);
ShowDataPointer(b)
pr = 7fe94d36e5e0
function ShowDataPointer(x)
orig = format('debug');
s = formattedDisplayText(x);
c = strtrim(strsplit(s, '\n'));
disp(c(startsWith(c, 'pr')));
format(orig);
end
With real values only, the data are shared. (For other readers. I'm aware, that you, Bruno, know this.)
My conclusion: dot.m is not efficiently implemented. Why? For future improvements.
I do not see a reason, why (:) creates a deep data copy, so I'd consider this as a bug. Did you ask MathWorks already for an explanation?
By the way, Matlab's cross() could be 10 times faster when implemented as MEX function.

Community Treasure Hunt

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

Start Hunting!

Translated by