7

I'm interfacing MATLAB with C/C++ using the MATLAB Engine API.

In my particular case MATLAB is used to calculate something and result is printed in C. However, throughout various test on both sides I noticed significant performance losses in C.

Here is an example of the MATLAB function calls:

tic;
data = predictIM(data);
toc;

On the C side I call similar functions as follows:

iMod::Timer_T<high_resolution_clock> t;

engPutVariable(ep, "data", dataContent);
engEvalString(ep, "[posture] = predictIM(data);");

UT_NOTIFY(LV_DEBUG,"The execution took "<<t.seconds());

My timer implementation in C++ looks as follows:

template< class Clock >
class Timer_T
{
   typename Clock::time_point start;
   public:
      Timer_T() : start( Clock::now() ) {}
      typename Clock::duration elapsed() const {
        return Clock::now() - start;
      }
      double seconds() const {
        return elapsed().count() *
          ((double)Clock::period::num/Clock::period::den);
      }
};

The above MATLAB code runs at approximately 180 frames per second including setting the matrix (data), whereas the C code only at 24 FPS. I used tic/toc to measure the execution time in MATLAB whereas my own timer implementation is used on the C/C++ side.

While profiling the application I noticed that the MATLAB Engine calls are the bottleneck. I know that the Linux MATLAB Engine implementation is using named pipes for interfacing with MATLAB and I was wondering if there is a way to speed up the communication of MATLAB with its Engine?

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
Dave
  • 71
  • 4
  • That's not C, that's C++. – Some programmer dude Oct 20 '14 at 07:43
  • True. Sorry for not being clear. I implemented the Matlab Engine in C and calculate the timings in C++ (where I use the Matlab results further) – Dave Oct 20 '14 at 07:51
  • 1
    @Dave: I think there's nothing you could do really, the Engine API is just another layer which adds overhead because of all the data marshaling back and forth... I'm assuming you connect to MATLAB once at start, and reuse the opened connection for each computation, right? Opening and closing connection to MATLAB process repeatedly can be really slow. – Amro Oct 20 '14 at 08:58
  • @Amro: You're right I'm reusing the matlab engine. Opening the engine is indeed very slow. I haven't implemented the Windows COM API. Do you think it will be faster then the Linux Engine Implementation? – Dave Oct 20 '14 at 09:21
  • 1
    @Dave: Honestly I don't know.. May I ask what is your application doing? If performance is really critical, maybe you could use [MATLAB Coder](http://www.mathworks.com/products/matlab-coder/) to convert your MATLAB function into standalone C/C++ code, which you can then compile as native library, with no MATLAB dependency at all. – Amro Oct 20 '14 at 09:31
  • @Amro: I use Matlab to record and detect human motions for human-agent interactions. Matlab is then mainly used to animate a virtual character in fully immersive environments. So, the more frames I can compute the faster the virtual agents response is going to be. I'll check if I can use MATLAB Coder to compile my library. Thanks for pointing that out. – Dave Oct 20 '14 at 10:34
  • As of now, I'm using the instruments toolbox and we are able to communicate via UDP. This circumvents our initial goal of using the Matlab engine but it is about 10 times faster. I believe it is the overhead that was slowing down the Engine- – Dave Aug 22 '16 at 06:47

1 Answers1

1

First, it's not fair to measure MATLAB engine like that. You should only time the computation time just as you did in the MATLAB, like this:

engPutVariable(ep, "data", dataContent);                // you should not time this

iMod::Timer_T<high_resolution_clock> t;
engEvalString(ep, "[posture] = predictIM(data);");      // time this only for fair
UT_NOTIFY(LV_DEBUG,"The execution took "<<t.seconds()); 

Actually, from my experience, running MATLAB and calling its engine in C/C++ should have similar speed as they actually depend the MATLAB software itself.

Second, I do have an advice for possible speedup. You should only open single MATLAB engine throughout your C/C++ project, instead of creating one for each call. Like this:

int main()
{
    // Open MATLAB engine for the whole project
    Engine *ep = engOpen(NULL);

    // Use it multiple times
    for (int i=0; i<100; ++i){
        engEvalString(ep, ...);
    }

    // Close MATLAB engine
    engClose(ep);

    return 0;
}
herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
  • 2
    I included the time for pushing variables into the Matlab workspace since it significantly slows down the execution time. In my particular case setting a 3x16 matrix takes 15ms while using it and computing a result takes 28ms. Retrieving the result takes another 20ms. Hence measuring the time for setting/getting matrices seems important to the overall performance. In my implementation I only the Matlab engine once. – Dave Oct 26 '14 at 07:12