Mex-function performance when setting handle object properties

I've encountered a frustrating delay in matlab execution after setting handle object properties within a mex-function. Here's how to reproduce it:
>> mex mexperftest.cpp
Building with 'MinGW64 Compiler (C++)'.
MEX completed successfully.
>> obj = Perftest();
>> tic; for j = 1:2000, mexperftest(obj); end; disp(toc);
0.1539
The operation takes only 0.15 seconds on my PC which is ok, but the matlab prompt appears only after about 3 seconds delay. You can actually measure this delay if you enter 'toc' at the command prompt during the delay:
>> obj = Perftest();
>> tic; for j = 1:2000, mexperftest(obj); end; disp(toc);
0.1424
toc
Elapsed time is 3.065224 seconds.
Perftest is merely a handle object with a single property and mexperftest function assigns value to this property.
Perftest.m:
classdef Perftest < handle
properties
prop
end
end
mexperftest.cpp:
#include "mex.hpp"
#include "mexAdapter.hpp"
using namespace matlab::data;
using matlab::mex::ArgumentList;
class MexFunction : public matlab::mex::Function {
public:
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr;
ArrayFactory factory;
void operator()(ArgumentList outputs, ArgumentList inputs) {
matlabPtr = getEngine();
ObjectArray obj( inputs[0] );
matlabPtr->setProperty( obj, u"prop", factory.createScalar<double>(1.0) );
}
};
What I've noticed is that it is impossible to profile this delay with matlab profiler. Looks like Matlab does something under the hood like freeing resources or something, and I have no idea how to workaround this. The delay is proportional to the number of properties assigned and the number of function calls. As such, it gets unbearable when scaled to any real project. So, the question is what can we do about it.

6 commentaires

It should related to Mex Engine API and calling getEngine in the loop (I'mnot using it at all), in regular Mex nothing odd like that happens.
Hm, if you make Perftest a regular object (not handle), there is no delay even though getEngine is still there. So I bet it is some issue with handle objects.
Really? I remove the object seeting property
#include "mex.hpp"
#include "mexAdapter.hpp"
using namespace matlab::data;
using matlab::mex::ArgumentList;
class MexFunction : public matlab::mex::Function {
public:
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr;
ArrayFactory factory;
void operator()(ArgumentList outputs, ArgumentList inputs) {
matlabPtr = getEngine();
//ObjectArray obj( inputs[0] );
//matlabPtr->setProperty( obj, u"prop", factory.createScalar<double>(1.0) );
}
}
And there is still 1s delay
>> tic; for j = 1:2000, mexperftest(obj); end; toc;
Elapsed time is 0.084104 seconds.
toc
Elapsed time is 0.981360 seconds.
>> tic; for j = 1:2000, mexperftest(obj); end; toc;
Elapsed time is 0.084269 seconds.
toc
Elapsed time is 1.049737 seconds.
>> tic; for j = 1:2000, mexperftest(obj); end; toc;
Elapsed time is 0.085578 seconds.
toc
Elapsed time is 0.990366 seconds.
>>
Calling engine is like open an whole 2nd matlab process somewhere. Very inefficient if you look for something fast.
I would suggest just using regular MEX (mexperftest.c).
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mxSetProperty(prhs[0], 0, "prop", mxCreateDoubleScalar(1.0));
}
After some investigation, delay appears as long as I pass handle object to C++ style mex function. It does not depend on getEngine(), however it does gets longer when calling setProperty method.
Indeed, your "regular" C-style mex function works 10 times faster and with no delay. Seems strange to me since Mathworks recommends C++ style Matlab Data API as the preferred solution. Thank you for your advice and participation. Hopefully someone from Mathworks can comment on this, too.
"Seems strange to me since Mathworks recommends C++ style Matlab Data API as the preferred solution."
I have those tendency since few years. The API C++ is preferred because they can better hide the machinery behind (they just don't us to know all those sharing data behind the scenes), and probably the new-generation of developers of TMW prefers OOP.
Which is pitty. When I do C-MEX, I want to do some stuffs that mke MATLAB works faster, and sometime do some exotic stuffs to avoid memory data moving around. The new trend of TMW goes againts it.
I encountered similar issue. My MEX function is a more complicated. After I replaced matlab script with C++ MEX function I found that new implementation needs more or less same time to compute things. For some data inputs C++ implementation is even slower than Matlab ! This was surprise for me. I profiled my code using Visual Studio and found that most of the time program spend in getProperty and setProperty functions ! The volume of data that I exchange with Matlab core is very low - 121 short strings and few hundred of doubles.

Connectez-vous pour commenter.

Réponses (0)

Produits

Question posée :

le 23 Oct 2020

Commenté :

le 6 Jan 2022

Community Treasure Hunt

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

Start Hunting!

Translated by