Good afternoon, dear habrovchane!
I would like to bring to your attention the article that the recent post
Matlab cluster did to me
with my own hands . At one time I ran into the same problems as the author of the topic, but to increase the performance I did not go into the wilds of distributed computing, but simply decided to optimize my code as much as possible. How to do this in Matlab, please under the cat for details.
The article is a description of life experience and free translation of the English-language
publication .
It is no secret that large-scale numerical calculations impose considerable demands on computer hardware. Sitting at my dissertation, I realized that my home computer had ceased to satisfy my computational needs. Since two months ago I changed the computer and collected the top-end hardware, the option of changing the hardware did not work for me. There is an opinion that code optimization is not a very important matter, it’s easier just to increase the costs of acquiring more modern hardware, and this opinion has a right to exist, but I don’t share it and therefore I climbed into my code and into special literature.
')
Matlab refers to interpreted languages, which would seem to make it not an appropriate language for large-scale scientific computing. All potential features of the language are realized through an extensive set of libraries and vectorization operations. The concept of vectorization is central to understanding how to write effective Matlab code. All data is stored in RAM in the form of vectors, therefore, the speed of operation of numerical algorithms in Matlab directly depends on the use of the vectorization operation.
Below are some basic excerpts from the official Matlab documentation that will help you in writing effective procedures in Matlab. You can become obsessed and spend outrageously many man-hours of working time to optimize the code, which will help win only a few seconds while the program is running, but again, saying that it was my production need.
The performance of your programs can increase significantly if you use the techniques below:
- Use vector operations, not loops;
- Use preallocation for vectors and matrices;
Consider each of these points in more detail.
Using vector operations instead of loops
Consider the following example:
dx = pi/30;
nx = 1 + 2*pi/dx;
for i = 1:nx
x(i) = (i-1)*dx;
y(i) = sin(3*x(i));
end
It is quite obvious that the creation of vectors x and y takes place in it. However, Matlab allocates memory for variables on the fly. During the first pass of the cycle, two vectors are created one at a time long by one. At each next step, the length of the vectors increases. During each cycle run, memory will be allocated for variables by Matlab, which takes CPU time.
It is preferable to use the following method of defining vectors:
x = 0:pi/30:2*pi
y = sin(3*x);
The first line of code creates a row vector x, which allocates the size of the memory corresponding to its length and the elements of the vector are stored in adjacent RAM cells. The second line of code initiates the creation of a second vector line, under which Matlab immediately allocates the necessary memory, without returning more to this issue.
Remember the main thing: Matlab is more adapted to vector and matrix calculations, which is what it was designed for.
Preallocation of memory for vectors and matrices
Although Matlab automatically adjusts the size of vectors and matrices, it’s still better to pre-allocate matrices. Pre-allocation assumes the cost of allocating memory only once, and this ensures that the matrix elements will be stored in adjacent memory cells (column by column).
Consider the following code:
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
This is a non-optimized code, as we are people thinking, we know the size of the vectors x and y, and we can use this knowledge:
dx = pi/30;
nx = 1 + 2*pi/dx;
nx2 = nx/2;
x = zeros(1,nx);
y = zeros(1,nx);
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
This code has been converted, but there are still pieces to which the preallocation rule can be applied. The vectors x (i) = ..., and y (i) = ... do not take advantage of vectorization.
The best thing would be to write this:
dx = pi/30;
nx = 1 + 2*pi/dx;
nx2 = nx/2;
x = zeros(1,nx);
y = x;
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
I hope this article will be useful to someone else, at one time it saved me a lot of waiting time and helped me successfully accomplish the task.