Matlab mex file медленнее по сравнению с его прямым C-эквивалентом - PullRequest
22 голосов
/ 08 марта 2011

Я затрудняюсь объяснить (и избежать) различий в скорости между программой Matlab mex и соответствующей программой на C без интерфейса Matlab.Я профилировал программу численного анализа:

int main(){

Well_optimized_code();

}

, скомпилированный с gcc 4.4 против эквивалента Matlab-Mex (направлен на использование gcc44, который в настоящее время не поддерживается Matlab, но требуется для другихпричины):

void mexFunction(int nlhs,mxArray* plhs[], int nrhs, const mxArray* prhs[]){

Well_optimized_code(); //literally the exact same code

}

Я выполнил время как:

$ time ./C_version

против

>> tic; mex_version(); toc

Разница во времени ошеломляет.Запуск версии из командной строки занимает в среднем 5,8 секунды.Версия в Matlab запускается за 21 секунду.Для контекста, mex-файл заменяет алгоритм в наборе инструментов SimBiology, выполнение которого занимает около 26 секунд.

По сравнению с алгоритмом Matlab версии C и mex линейно масштабируются до 27 потоков с использованием вызовов openMP,но в целях профилирования эти вызовы были отключены и закомментированы.

Две версии были скомпилированы одинаково, за исключением необходимых флагов для компиляции в виде mex-файла: -fPIC --shared-lmex -DMATLAB_MEX_FILE, применяемый в mex-компиляции / компоновке.Я удалил все ссылки на левый и правый аргументы mex-файла.То есть, он не принимает никаких входных данных и не дает никаких выходных данных, он предназначен исключительно для профилирования.

Великий и славный Google сообщил мне, что независимый от позиции код не должен быть источником замедления и, кроме того, что яЯ в растерянности.

Любая помощь будет оценена,

Андрей

Ответы [ 2 ]

14 голосов
/ 22 апреля 2011

После месяца переписки по электронной почте с моими контактами в Mathworks, игры с моим собственным кодом и профилирования моего кода в любом случае, у меня есть ответ;тем не менее, это может быть самый неудовлетворительный ответ, который у меня когда-либо был на технический вопрос:

Короткая версия: «Обновление до версии Matlab 2011a (официально выпущенной на прошлой неделе), эта проблема теперь решена».

Более длинная версия связана с проблемой издержек, связанных со шлюзом mex в версиях 2010b и более ранних.Лучшее объяснение, которое я смог извлечь, состоит в том, что эти издержки не оцениваются один раз, мы платим немного каждый раз, когда функция вызывает другую функцию, которая находится в связанной библиотеке.

Хотя почему это происходитсбивает с толку, это по крайней мере согласуется с профилированием АКУЛЫ, которое я сделал.Когда я профилирую и сравниваю различия между нативным и мекс-приложением, возникает повторяющаяся картина.Время, потраченное на функции из исходного кода, который я написал для приложения, не меняется.Время, затрачиваемое на библиотечные функции, немного увеличивается при сравнении нативных и мексиканских реализаций.Функции в другой библиотеке, используемые для создания этой библиотеки, значительно увеличивают разницу.Разница во времени продолжает увеличиваться по мере того, как мы продвигаемся все глубже, пока не достигнем реализации BLAS.

Несколько часто используемых функций BLAS были основными виновниками.Функция, которая занимала ~ 1% моего времени вычислений в нативном приложении, работала на 30% в функции mex.

Реализация шлюза mex, по-видимому, изменилась между 2010b и 2011a.На моем macbook нативное приложение занимает около 6 секунд, а версия mex - 6,5 секунды.Это накладные расходы, с которыми я могу справиться.

Что касается основной причины, я могу только строить догадки.Matlab имеет свои корни в интерпретирующем кодировании.Поскольку мекс-функции являются динамическими библиотеками, я предполагаю, что каждая мекс-библиотека не знала, с чем она была связана, до времени выполнения.Поскольку Matlab предлагает пользователю редко использовать mex, а затем только для небольших вычислительных блоков, я предполагаю, что большие программы (такие как решатель ODE) реализуются редко.Эти программы, как и моя, страдают больше всего.

Я профилировал несколько функций Matlab, которые, как я знаю, были реализованы в C, затем скомпилирован с использованием mex (особенно sbiosimulate после вызова sbioaccelerate в кинетических моделях)., часть набора инструментов SimBiology), и, похоже, есть некоторые существенные ускорения.Таким образом, обновление 2011a представляется более полезным, чем обычное полугодовое обновление.

Удачи другим программистам с аналогичными проблемами.Спасибо за все полезные советы, которые помогли мне начать в правильном направлении.

- Андрей

3 голосов
/ 08 марта 2011

Напомним, что Matlab хранит массивы как мажорные столбцы, а C / C ++ - как мажорные строки.Возможно ли, что ваша структура / алгоритм цикла итеративно проходит ряды строк, что приводит к плохому времени доступа к памяти в Matlab, но к быстрому времени доступа в C / C ++?

...