2014-10-20 3 views
6

Я взаимодействую с MATLAB с C/C++, используя MATLAB Engine API.Ускорение вызова Matlab Engine

В моем конкретном случае MATLAB используется для вычисления что-то и результат выводится в 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 кадров в секунду. Я использовал tic/toc для измерения времени выполнения в MATLAB, тогда как моя собственная реализация таймера используется на стороне C/C++.

При профилировании приложения я заметил, что вызовы MATLAB Engine являются узким местом. Я знаю, что реализация Linux MATLAB Engine использует именованные каналы для взаимодействия с MATLAB, и мне было интересно, есть ли способ ускорить связь MATLAB с его Engine?

+0

Это не C, это C++. –

+0

Правда. Извините за то, что я не понимаю. Я реализовал Matlab Engine в C и вычислил тайминги в C++ (где я снова использую результаты Matlab) – Dave

+1

@Dave: Я думаю, что вы ничего не можете сделать, API Engine - это еще один уровень, который добавляет накладные расходы из-за всех данных marshaling взад-вперед ... Я предполагаю, что вы подключаетесь к MATLAB один раз при запуске и повторно используете открытое соединение для каждого вычисления, не так ли? Открытие и закрытие соединения с процессом MATLAB неоднократно может быть очень медленным. – Amro

ответ

1

Во-первых, несправедливо измерить двигатель 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; 
} 
+1

Я включил время для перетаскивания переменных в рабочую область Matlab, поскольку это значительно замедляет время выполнения. В моем конкретном случае установка матрицы 3x16 занимает 15 мс при ее использовании, а вычисление результата занимает 28 мс. Получение результата занимает еще 20 мс. Следовательно, измерение времени установки/получения матриц представляется важным для общей производительности. В моей реализации я только один движок Matlab. – Dave

Смежные вопросы