Подтвердить что ты не робот

Файл Matlab mex медленный по сравнению с его прямым эквивалентом C

Я затрудняюсь объяснить (и избежать) различия в скорости между программой 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 сообщил мне, что независимый от позиции код не должен быть источником замедления, и за его пределами я нахожусь в убытке.

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

Эндрю

4b9b3361

Ответ 1

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

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

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

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

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

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

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

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

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

- Эндрю

Ответ 2

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