I have some Matlab code that is run many millions of times as mentioned in this question: Matlab: Does calling the same mex function repeatedly from a loop incur too much overhead?
I'm trying to mex-ify it to see whether that helps. Now, when I generate code from the Matlab code using Matlab Coder tool, the code is generally reasonable, but this one line of Matlab code (in a C++ comment in the first line below) begets this monstrosity, and I have no idea why. Any help in understanding and reducing its complexity would be appreciated.
For context, d is a two dimensional matrix, and s1 is a row vector. s1_idx is assigned to be length(s1) + 1 in preceding C++ code,
/* d(:, 1) = 0:length(s1); */
cdiff = s1_idx_0 - 1;
for (nm1d2 = 0; nm1d2 <= cdiff; nm1d2++) {
tmp_data[nm1d2] = nm1d2;
}
ndbl = (int32_T)muDoubleScalarFloor((real_T)s1_sizes[1] + 0.5);
apnd = ndbl;
cdiff = ndbl - s1_sizes[1];
if (muDoubleScalarAbs((real_T)cdiff) < 4.4408920985006262E-16 * (real_T)s1_sizes[1]) {
ndbl++;
apnd = s1_sizes[1];
} else if (cdiff > 0) {
apnd = ndbl - 1;
} else {
ndbl++;
}
if (ndbl > 0) {
b_tmp_data[0] = 0.0;
if (ndbl > 1) {
b_tmp_data[ndbl - 1] = (real_T)apnd;
nm1 = ndbl - 1;
nm1d2 = nm1;
nm1d2 = (int32_T)((uint32_T)nm1d2 >> 1);
for (cdiff = 1; cdiff <= nm1d2 - 1; cdiff++) {
b_tmp_data[cdiff] = (real_T)cdiff;
b_tmp_data[(ndbl - cdiff) - 1] = (real_T)(apnd - cdiff);
}
if (nm1d2 << 1 == nm1) {
b_tmp_data[nm1d2] = (real_T)apnd / 2.0;
} else {
b_tmp_data[nm1d2] = (real_T)nm1d2;
b_tmp_data[nm1d2 + 1] = (real_T)(apnd - nm1d2);
}
}
}
cdiff = s1_idx_0 - 1;
for (nm1d2 = 0; nm1d2 <= cdiff; nm1d2++) {
SD->f0.d_data[tmp_data[nm1d2]] = b_tmp_data[nm1d2];
}
That's pretty funny generated code for what you actually want to accomplish. You just want to stuff the integers 0 to k into an array. But the code generator is built to deal with the general case. So there are three parts to the generated code:
:
expression, but you could have used something else. The code generator has to be prepared for you doing something like d(length(s1):0, 1)=0:length(s1)
. In the end, it might be that all you need is:
cdiff = s1_idx_0 - 1;
for (nm1d2 = 0; nm1d2 <= cdiff; nm1d2++) {
SD->f0.d_data[nm1d2] = nm1d2;
}
MatLab is a special case, designed to work with special math functions. You do realize that under the hood stuff is still being translated to lots of machine code which processor can understand.
There are a lot of questions on SO that ask the same thing: "why is XX so easy to do in Matlab and so hard in C++?". Because Matlab was designed for this while C++ is a general-purpose language.
Matlab developers had to write those big code sheets to provide you a way to use this functionality with just one line. C++ doesn't have it in the standard library, thus you will need to make it yourself.
Well, take a simple example. Assume users A and B want to solve a quadratic equasion. User A is using a mathematical package, and all he has to do is write
FIND x IN 2x 2 + 6x + 3 = 0
User B, on the other hand, is using C++, and he has to write a function to count the discriminant, compute the values (he'll have to worry about negative discriminant too of course) and output them, something that the developers of the mathematical package had already done for user A. That is a lot of code really, here's an example that I quickly googled.
Now imagine user A saying "Hey, B, why the hell do you need to write so much code? I can do it in just 1 line!" and this will be your case ;)
Also don't forget that automatically-generated code is not always the best code ever if you talk about readability and ease of understanding by human.
I'm late to this party, but the existing answers focus on why it happened and don't discuss what you can do about it.
If you know which line causes that strange, messy looking C code, you should try changing that line. Instead of:
d(:, 1) = 0:length(s1);
One thing to try is removing the dependency on variable s1
:
d(:, 1) = 0:size(d,1);
Another option is to write a simple loop that can be almost directly translated to C. Hopefully codegen will give very similar and simple C code.
for i = 0:size(d,1)
d(i,1) = i;
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.