Я связываю MATLAB с C / C ++, используя MATLAB Engine API.
В моем конкретном случае MATLAB используется для вычисления чего-либо, и результат выводится на C. Однако в ходе различных испытаний с обеих сторон я заметил значительные потери производительности на C.
Вот пример вызова функции MATLAB:
tic;
data = predictIM(data);
toc;
На стороне C я вызываю похожие функции следующим образом:
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());
Моя реализация таймера в C ++ выглядит следующим образом:
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);
}
};
Приведенный выше код MATLAB работает со скоростью примерно 180 кадров в секунду, включая установку матрицы (data
), тогда как код C только на 24 FPS. я использовал tic
/toc
для измерения времени выполнения в MATLAB, в то время как моя собственная реализация таймера используется на стороне C / C ++.
Во время профилирования приложения я заметил, что вызовы MATLAB Engine являются узким местом.
Я знаю, что реализация Linux MATLAB Engine использует именованные каналы для взаимодействия с MATLAB, и мне было интересно, есть ли способ ускорить взаимодействие MATLAB с его Engine?
Во-первых, было бы несправедливо измерить двигатель MATLAB таким образом. Вы должны рассчитывать время вычислений только так, как вы это делали в MATLAB, вот так:
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());
На самом деле, исходя из моего опыта, запуск MATLAB и вызов его движка на C / C ++ должны иметь схожую скорость, поскольку они на самом деле зависят от самого программного обеспечения MATLAB.
Во-вторых, у меня есть совет для возможного ускорения. Вы должны открывать только один движок MATLAB во всем проекте C / C ++ вместо того, чтобы создавать его для каждого вызова. Как это:
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;
}