Prevent loop merging in Matlab coder
1 visualización (últimos 30 días)
Mostrar comentarios más antiguos
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;
}
0 comentarios
Respuestas (1)
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
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);
% }
Ver también
Categorías
Más información sobre MATLAB Coder 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!