Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C and Matlab: Why does this one line in Matlab become so many lines in C++ code generated by Matlab Coder?

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];
}
like image 938
Sundar R Avatar asked Oct 18 '12 12:10

Sundar R


People also ask

What is C in MATLAB?

Directly call C library functionality from MATLAB® using calllib or write C programs that call MATLAB functions using mxArray to access or create MATLAB variables in C. MATLAB provides multiple interfaces to C and C++ language programs. Whenever possible, choose the C++ interfaces over the C-only versions.

Can you convert MATLAB code to C?

To convert MATLAB® Code to fixed-point C Code using the MATLAB Coder™ app: Open the MATLAB Coder app. On the Select Source Files page, add the entry-point function from which you want to generate code. Set Numeric Conversion to Convert to fixed point .

Which is faster MATLAB or C++?

C++ averages a processing speed that is over 500 times faster than Matlab code. Not only does this apply for this code, but this can also be applied for any other code comparison between Matlab and C++ MEX-files. In comparison, the benefits of speed offered by C++ far outweigh the simplicity of Matlab.


1 Answers

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:

  1. Create an array of indices specifying where, on the left-hand side, the elements from the right-hand side will go. You used the : 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).
  2. Create an array of values for the right-hand side. Your just doing sequential integers, but the code generator is prepared to deal with doubles and when creating values from a range of doubles you might have funny rounding issues. It's checking for all kinds of edge cases.
  3. Finally, there's the loop that actually assigns the values on the right-hand side to memory slots on the left-hand side as indexed by the array created in step 1.

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;
}
like image 199
JCooper Avatar answered Oct 14 '22 01:10

JCooper