Matlab 版 (精华区)

发信人: bage (愿), 信区: Matlab
标  题: Improving the Speed of MATLAB Calculations
发信站: 哈工大紫丁香 (2002年11月20日14:58:09 星期三), 站内信件

Large scale numerical calculations can put heavy demands on your computer. 
Some software companies argue that they do not have to do a good job of perf
ormance tuning because computer hardware is advancing so rapidly. While it m
ay be possible to foist slug-like word-processors onto the average computer 
user, engineers and scientists are usually less tolerant of poorly designed 
and implemented software.
In technical markets the gains in computing performance raise, not lower, th
e expectations of users. It is often the case that improved hardware and sof
tware allows simulations to be run with more detail, which often translates 
to more realistic results.
MATLAB programs are interpretted. This would seem to make it inapproapriate 
for large scale scientific computing. The power of MATLAB is realized with i
ts extensive set of libraries which are compiled or are carefully coded in M
ATLAB to utilize ``vectorization''. The concept of vectorization is central 
to understanding how to write efficient MATLAB code.
Vectorized code takes advantage, wherever possible, of operations involving 
data stored as vectors. This even applies to matrices since a MATLAB matrix 
is stored (by columns) in contiguous locations in the computer's RAM. The sp
eed of a numerical algorithm in MATLAB is very sensitive to whether or not v
ectorized operations are used.
This section presents some basic considerations to writing efficient MATLAB 
routines. It is possible, of course, to become obsessed with performance and
 waste man-hours of programming time in order to save a few seconds of execu
tion time. The ideas presented below require little extra effort, yet can yi
eld significant speed improvements. Once you understand how to use these pro
cedures they will become natural parts of your MATLAB programming style.
For a more advanced discussion of vectorization techniques be sure to check 
the Mathworks Home Page and in particular their technical notes
The following topics are covered in this section
Using vector operations instead of loops
Pre-allocating memory for vectors and matrices
Correct code is most important
----------------------------------------------------------------------------
----
Using vector operations instead of loops
Consider the following loop, translated directly from Fortran or C
  dx = pi/30;
  nx = 1 + 2*pi/dx;
  for i = 1:nx
     x(i) = (i-1)*dx;
     y(i) = sin(3*x(i));
  end
The preceding statements are perfectly legal MATLAB statements, but they are
 an inefficient way to create the x and y vectors. Recall that MATLAB alloca
tes memory for variables on the fly. On the first time through the loop (i=1
), MATLAB creates two row vectors x and y, each of length one. On each subse
quent pass through the loop MATLAB appends new elements to x and y. Not only
 does this incur extra overhead in the memory allocation calls, the elements
 of x and y will not be stored in contiguous locations in RAM. Thus, any sub
sequent operations with x and y, even though these operations may be vectori
zed, will take a performance hit because of memory access overhead.
The preferred way to create the same two x and y vectors is with the followi
ng statements.
  x = 0:pi/30:2*pi
  y = sin(3*x);
The first statement creates the row vector, x, with 1 + pi/15 elements store
d in contiguous locations in RAM. The second statement creates a new (matrix
) variable, y, with the same number of rows and columns as x. Since x is a r
ow vector, as determined by the preceding step, y is also a row vector. If x
 were, for example, a 5 by 3 matrix, then y = sin(3*x) would create a 5 by 3
 matrix, y.
MATLAB is designed to perform vector and matrix operations efficiently. To t
ake maximum advantage of the computer hardware at your disposal, therefore, 
you should use vectorized operations as much as possible.
----------------------------------------------------------------------------
----
Pre-allocating memory for vectors and matrices
Though MATLAB will automatically adjust the size of a matrix (or vector) it 
is usually a good idea to pre-allocate the matrix. Pre-allocation incurs the
 cost of memory allocation just once, and it guarantees that matrix elements
 will be stored in contiguous locations in RAM (by columns).
Consider the following (admitedly artificial) sequence of statements.
  dx = pi/30;
  nx = 1 + 2*pi/dx;
  nx2 = nx/2;
  for i = 1:nx2
     x(i) = (i-1)*dx;
     y(i) = sin(3*x(i));
  end
  for i = nx2+1:nx
     x(i) = (i-1)*dx;
     y(i) = sin(5*x(i));
  end
Since we know the size of x and y, a priori, we can pre-allocate memory for 
these vectors. Pre-allocation involves creating a matrix (or vector) with on
e vectorized statement before any of the matrix elements are referenced indi
vidually. The ones and zeros functions are typically used to pre-allocate me
mory.
Here is an improvement of the preceding statements with pre-allocation of me
mory for x and y.
  dx = pi/30;
  nx = 1 + 2*pi/dx;
  nx2 = nx/2;
  x = zeros(1,nx);      % pre-allocate row-vectors, x
  y = zeros(1,nx);      % and y
  for i = 1:nx2
     x(i) = (i-1)*dx;
     y(i) = sin(3*x(i));
  end
  for i = nx2+1:nx
     x(i) = (i-1)*dx;
     y(i) = sin(5*x(i));
  end
The statements x(i) = ..., and y(i) = ... still do not take advantage of pos
sibilities for vectorization, but at least the elements of x and y are store
d contiguously in RAM. We will improve the efficiency of the loops shortly. 
First, however, note that we could have written the pre-allocation statement
s as
  x = zeros(1,nx);      % pre-allocate row-vectors, x
  y = x;                % and y
The statement y = x does not mean that y will stay equal to x. It simply cre
ates another matrix y with the same ``shape'' as x. Understanding that pre-a
llocation is important for efficiency will help you understand these apparen
tly confusing twists of MATLAB programming logic.
We can further improve our loops by pulling the assignment of x out of the l
oops.
  x = 0:pi/30:2*pi;     % vectorized calculation of x
  nx = length(x);
  nx2 = nx/2;
  y = x;                % pre-allocate memory for y
  for i = 1:nx2
     y(i) = sin(3*x(i));
  end
  for i = nx2+1:nx
     y(i) = sin(5*x(i));
  end
Finally, if we're obsessed with performance, we observe that the calculation
 of y can also be vectorized. To do this we use the colon notation to refer 
to segments of the x and y vectors.
  x = 0:pi/30:2*pi;     % vectorized calculation of x
  nx = length(x);
  nx2 = nx/2;
  y = x;                             % pre-allocate memory for y
  y(1:nx2) = sin(3*x(1:nx2));        % compute first part of y
  y(nx2+1:nx) = sin(5*x(nx2+1:nx));  % and the second part
To those new to MATLAB programming, the preceding statements may appear unec
essarily obfuscated. The comment statements, of course, help, but the logic 
behind the logic comes from a true understanding of vectorization. Once you 
get the hang of MATLAB's colon notation you too will come to write code like
 this. Whenever the speed of MATLAB code is important, there is no substitut
e for vectorization.
----------------------------------------------------------------------------
----
Correct code is always more important than speed
Vectorization sometimes makes MATLAB code hard to read. If you find yourself
 puzzling over the code, or more importantly if you find yourself wondering 
if the code performs the correct calculation, then stop trying to optimize p
erformance.
Always remember
Code that gives incorrect, or inaccurate results is useless, no matter how f
ast it executes.

--
           ooooO    Ooooo      *********************************
           (    )   (    )     #    大肚能容,容天下难容之事    #  
            \  (     )  /      #    开口便笑,笑世间可笑之人    #
             \  )   (  /       *********************************
              ~~     ~~

※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.226.4]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.472毫秒