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

9 visualizaciones (últimos 30 días)
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!

Respuesta aceptada

Matt J
Matt J el 18 de Abr. de 2018
Editada: Matt J el 18 de Abr. de 2018

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 comentarios

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Matrix Indexing en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by