Prevent loop merging in Matlab coder
2 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
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 Commenti
Risposte (1)
Matan Silver
il 25 Apr 2022
Modificato: Matan Silver
il 25 Apr 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 Commento
Matan Silver
il 25 Apr 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);
% }
Vedere anche
Categorie
Scopri di più su Function Definition in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!