Prevent loop merging in Matlab coder

1 visualización (últimos 30 días)
Marc Barnada
Marc Barnada el 25 de Abr. de 2022
Comentada: Matan Silver el 25 de Abr. de 2022
Matlab tends to merge for loops of the same size as:
xyz = zeros(2048,3);
for i = 1:size(xyz,1)
xyz(i,:)= 123;
end
di=nan(2048,1);
Then the code generated in C++ will be:
for (i=0; i<2048; i++){
for (j=0; j<3; j++){
xyz[i * 3 + j] = 123;
}
di[i] = rtNaN;
}
How can I let coder know that di should be in another for loop to obtain the best speed due to cache misses?
Desired behaviour:
for (i=0; i<2048; i++){
for (j=0; j<3; j++){
xyz[i * 3 + j] = 123;
}
}
for (i=0; i<2048; i++){
di[i] = rtNaN;
}

Respuestas (1)

Matan Silver
Matan Silver el 25 de Abr. de 2022
Editada: Matan Silver el 25 de Abr. de 2022
Hi Marc,
One way to achieve this is to factor out the initialization of the "di" variable into a non-inlined helper function. This will make sure it is not pulled into the loop. See below for the comparison:
function [xyz, di] = foo
xyz = zeros(2048,3);
for i = 1:size(xyz,1)
xyz(i,:)= 123;
end
di=nan(2048,1);
end
% void foo(double xyz[6144], double di[2048])
% {
% int i;
% for (i = 0; i < 2048; i++) {
% xyz[i] = 123.0;
% xyz[i + 2048] = 123.0;
% xyz[i + 4096] = 123.0;
% di[i] = rtNaN;
% }
% }
Compared to an example with the helper function:
function [xyz, di] = foo_noninline
xyz = zeros(2048,3);
for i = 1:size(xyz,1)
xyz(i,:)= 123;
end
di=initDI();
end
function di = initDI()
coder.inline('never');
di = nan(2048,1);
end
% static void initDI(double di[2048])
% {
% int i;
% for (i = 0; i < 2048; i++) {
% di[i] = rtNaN;
% }
% }
%
% /*
% * Arguments : double xyz[6144]
% * double di[2048]
% * Return Type : void
% */
% void foo_noninline(double xyz[6144], double di[2048])
% {
% int i;
% for (i = 0; i < 2048; i++) {
% xyz[i] = 123.0;
% xyz[i + 2048] = 123.0;
% xyz[i + 4096] = 123.0;
% }
%
% initDI(di);
% }
Hopefully this helps!
Matan
  1 comentario
Matan Silver
Matan Silver el 25 de Abr. de 2022
Side-note, depending on the architecture and environment, you could also get better performance by playing with "coder.rowMajor", which will change the dimension of the loop variables. For example, note how the three unrolled assignments in the loop are much closer to each other in memory now:
function [xyz, di] = foo_noninline
coder.rowMajor;
xyz = zeros(2048,3);
for i = 1:size(xyz,1)
xyz(i,:)= 123;
end
di=initDI();
end
function di = initDI()
coder.inline('never');
di = nan(2048,1);
end
% static void initDI(double di[2048])
% {
% int i;
% for (i = 0; i < 2048; i++) {
% di[i] = rtNaN;
% }
% }
%
% /*
% * Arguments : double xyz[6144]
% * double di[2048]
% * Return Type : void
% */
% void foo_noninline(double xyz[6144], double di[2048])
% {
% int i;
% for (i = 0; i < 2048; i++) {
% xyz[3 * i] = 123.0;
% xyz[3 * i + 1] = 123.0;
% xyz[3 * i + 2] = 123.0;
% }
%
% initDI(di);
% }

Iniciar sesión para comentar.

Categorías

Más información sobre MATLAB Coder en Help Center y File Exchange.

Productos


Versión

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by