How to improve matrix indexing efficiency or avoid indexing in Finite difference?

11 ビュー (過去 30 日間)
Hao Zhang
Hao Zhang 2018 年 4 月 17 日
コメント済み: Hao Zhang 2018 年 4 月 19 日
Hi all,
I am trying to optimize the performance of a FDTD (Finite-differnce-time-domain) code implemented in Matlab. As you may know, FDTD usually uses finite difference stencils in a time loop, i.e., the code calculates for example A(2:end,:)-A(1:end-1,:) many places in it. I've found that most of the time Matlab is spending on is not the actual subtracting or adding numbers, but the indexing.
For a very simple example, if I run this:
clear;
clc;
close all;
N1=100;
N2=100;
A=(ones(N1,N2,'single'));
C=(ones(N1,N2,'single'));
tic;
for i=1:1e4
%C(2:end,:)=C(2:end,:)-A(1:end-1,:);
C=C-A;
end
toc;
I got Elapsed time is 0.056711 seconds.
Instead if I run the following:
clear;
clc;
close all;
N1=100;
N2=100;
A=(ones(N1,N2,'single'));
C=(ones(N1,N2,'single'));
tic;
for i=1:1e4
C(2:end,:)=C(2:end,:)-A(1:end-1,:);
%C=C-A;
end
toc;
I got: Elapsed time is 0.316735 seconds.
That is to say the most of the time Matlab is just doing the matrix indexing, Is there any way to improve this or avoid the indexing but get the same result? This could make my code almost 10 times faster!

採用された回答

Matt J
Matt J 2018 年 4 月 18 日
編集済み: Matt J 2018 年 4 月 18 日

the code calculates for example A(2:end,:)-A(1:end-1,:) many places in it.

For simple cases like this, you should be using the built-in DIFF command,

    D=diff(A,1,1); %equivalent to A(2:end,:)-A(1:end-1,:)

That is to say the most of the time Matlab is just doing the matrix indexing

It is not the indexing itself that is slow. It is that the indexing statements on the right hand side result in the creation of temporary arrays. Indexing on the left hand side should not have this problem, e.g., something like,

for i=1:1e4
    C(2:end,:)=X-Y; 
end

You can work around this this by doing right-hand side indexing outside of the loop, so that temporary arrays will be created only once:

tic;
Ctmp=C(2:end,:); Atmp=A(1:end-1,:);
for i=1:1e4
  Ctmp=Ctmp-Atmp;
end
C(2:end,:)=Ctmp; A(1:end-1,:)=Atmp;
toc

If you have more complicated indexing that varies from iteration to iteration of the loop, you could also try this FEX file, although I haven't used it myself.

  3 件のコメント
Hao Zhang
Hao Zhang 2018 年 4 月 19 日
thanks!

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeResizing and Reshaping Matrices についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by