Prevent loop merging in Matlab coder

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;
}

답변 (1개)

Matan Silver
Matan Silver 2022년 4월 25일
편집: Matan Silver 2022년 4월 25일

0 개 추천

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

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);
% }

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 MATLAB Coder에 대해 자세히 알아보기

제품

릴리스

R2020b

질문:

2022년 4월 25일

댓글:

2022년 4월 25일

Community Treasure Hunt

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

Start Hunting!

Translated by