Почему я не вижу значительного ускорения при использовании компилятора MATLAB? - PullRequest
9 голосов
/ 26 сентября 2008

У меня есть много приятного кода MATLAB, который выполняется слишком медленно и было бы сложно переписать на C. Компилятор MATLAB для C, похоже, не сильно помогает, если вообще. Должно ли это ускорить выполнение больше? Я облажался?

Ответы [ 11 ]

22 голосов
/ 26 сентября 2008

Если вы используете MATLAB complier (в последней версии MATLAB), то вы почти наверняка не увидите никаких ускорений вообще. Это потому, что все, что на самом деле делает компилятор, это дает вам возможность упаковать свой код, чтобы он мог распространяться среди людей, у которых нет MATLAB. Он не конвертирует его во что-то более быстрое (например, машинный код или C) - он просто оборачивает его в C, чтобы вы могли вызвать его.

Это достигается тем, что ваш код запускается во время выполнения компилятора MATLAB (MCR), которое по сути является вычислительным ядром MATLAB - ваш код все еще интерпретируется. Благодаря штрафу, вызванному необходимостью вызывать MCR, вы можете обнаружить, что скомпилированный код работает медленнее, чем если бы вы просто запускали его на MATLAB.

Другими словами - вы можете сказать, что компилятор на самом деле не компилируется - по крайней мере, в традиционном смысле этого слова.

Старые версии компилятора работали по-разному, и в определенных ситуациях могли происходить ускорения. Для Mathwork принять это перейдите к

http://www.mathworks.com/support/solutions/data/1-1ARNS.html

19 голосов
/ 26 сентября 2008

По моему опыту, медленный код MATLAB обычно происходит из-за отсутствия векторизации вашего кода (то есть написания циклов for вместо простого умножения массивов (простой пример))

Если вы выполняете файловый ввод / вывод, следите за чтением данных по одному фрагменту за раз. Посмотрите в файлах справки для векторизованной версии fscanf.

Не забывайте, что в MATLAB тоже есть профилировщик!

14 голосов
/ 26 сентября 2008

Я повторю то, что сказал dwj: если ваш код MATLAB медленный, это возможно потому, что он недостаточно векторизован. Если вы выполняете явные циклы, когда можете выполнять операции над целыми массивами, это является причиной.

Это в равной степени относится ко всем ориентированным на массив динамическим языкам: Perl Data Language, Numeric Python, MATLAB / Octave и т. Д. Это даже в некоторой степени верно в скомпилированном коде на C и FORTRAN: специально разработанные библиотеки векторизации обычно используют осторожно внутренние циклы и SIMD-инструкции (например, MMX, SSE, AltiVec).

5 голосов
/ 11 октября 2008

Во-первых, я второй все вышеупомянутые комментарии о профилировании и векторизации.

Для исторической перспективы ...

Более старая версия Matlab позволяла пользователю конвертировать m файлов в функции mex, предварительно проанализировав код m и преобразовав его в набор вызовов библиотеки Matlab. Эти вызовы содержат все проверки ошибок, которые выполнял интерпретатор, но старые версии интерпретатора и / или анализатора онлайн работали медленно, поэтому компиляция m-файла иногда могла бы помочь. Обычно это помогало, когда у вас были циклы, потому что Matlab был достаточно умен, чтобы встроить кое-что из этого в C. Если у вас есть одна из этих версий Matlab, вы можете попробовать сказать mex-скрипту, чтобы сохранить файл .c, и вы можете увидеть, что именно делает.

В более поздней версии (вероятно, 2006a и более поздних, но я не помню) Mathworks начал использовать компилятор, работающий точно в срок, для интерпретатора. По сути, этот JIT-компилятор автоматически компилирует все mex-функции, поэтому явное выполнение этого в автономном режиме не помогает вообще. С тех пор в каждой версии они приложили много усилий, чтобы сделать переводчика намного быстрее. Я считаю, что более новые версии Matlab даже не позволяют автоматически компилировать m файлов в mex, потому что это больше не имеет смысла.

3 голосов
/ 21 ноября 2008

Компилятор MATLAB оборачивает ваш m-код и отправляет его во время выполнения MATLAB. Таким образом, производительность, которую вы видите в MATLAB, должна соответствовать производительности, которую вы видите с компилятором.

Для других ответов полезно векторизовать ваш код. Но MATLAB JIT довольно хорош в наши дни, и многие вещи работают примерно так же хорошо, как векторизованные или нет. Это не значит, что от векторизации не может быть выигрыша в производительности, это просто не та волшебная пуля, которой она когда-то была. Единственный способ действительно сказать, это использовать профилировщик, чтобы узнать, где ваш код видит узкие места. Часто есть места, где вы можете выполнить локальный рефакторинг, чтобы реально улучшить производительность вашего кода.

Существует несколько других аппаратных подходов, которые вы можете использовать для повышения производительности. Во-первых, большая часть подсистемы линейной алгебры является многопоточной. Вы можете убедиться, что вы включили это в своих предпочтениях, если вы работаете на многоядерной или многопроцессорной платформе. Во-вторых, вы можете использовать набор инструментов для параллельных вычислений, чтобы использовать преимущества нескольких процессоров. Наконец, если вы являетесь пользователем Simulink, вы можете использовать emlmex для компиляции m-кода в c. Это особенно эффективно для работы с фиксированной точкой.

2 голосов
/ 13 октября 2008

Вы пробовали профилировать свой код? Вам не нужно векторизовать ВСЕ свой код, только функции, которые доминируют во время выполнения. Профилировщик MATLAB подскажет вам, где ваш код тратит больше всего времени.

Есть много других вещей, которые вы должны прочитать в разделе Советы по повышению производительности в руководстве по MathWorks.

1 голос
/ 10 декабря 2008

Я бы проголосовал за профилирование + затем взглянул на узкие места.

Если узким местом является матричная математика, вы, вероятно, не добьетесь большего успеха ... ЗА ИСКЛЮЧЕНИЕМ, один большой недостаток - это распределение массива. например если у вас есть цикл:

s = [];
for i = 1:50000
  s(i) = 3;
end

Это должно продолжать изменять размер массива; гораздо быстрее запрессовать массив (начать с нулей или NaN) и заполнить его оттуда:

s = zeros(50000,1);
for i = 1:50000
  s(i) = 3;
end

Если узким местом является повторное выполнение большого количества вызовов функций, это непросто.

Если узким местом является то, что MATLAB не делает быстро (некоторые виды синтаксического анализа, XML и тому подобное), тогда я бы использовал Java, поскольку MATLAB уже работает на JVM и очень легко взаимодействует с произвольными файлами JAR. Я посмотрел на взаимодействие с C / C ++, и это действительно ужасно. С Microsoft COM все в порядке (только для Windows), но после изучения Java я не думаю, что когда-нибудь вернусь к этому.

1 голос
/ 17 ноября 2008

Вы можете перенести свой код на «Embedded Matlab», а затем использовать Realtime-Workshop, чтобы перевести его на C.

Встроенный Matlab является подмножеством Matlab. Он не поддерживает Cell-Arrays, Graphics, Marices динамического размера или некоторые режимы адресации Matrix. Может потребоваться значительное усилие для переноса на встроенный Matlab.

Realtime-Workshop является основой продуктов для генерации кода. Он выдает универсальный C или может оптимизировать для ряда встроенных платформ. Возможно, больше всего вас интересует xPC-Target, который рассматривает аппаратное обеспечение общего назначения как встроенную цель.

1 голос
/ 11 октября 2008

mcc совсем не ускорит ваш код - на самом деле это не компилятор.

Прежде чем сдаться, вам нужно запустить профилировщик и выяснить, куда уходит все ваше время (Инструменты-> Открыть профилировщик). Кроме того, разумное использование «тик» и «ток» может помочь. Не оптимизируйте свой код, пока не узнаете, куда идет время (не пытайтесь угадать).

Имейте в виду, что в Matlab:

  • операции на битовом уровне действительно медленные
  • медленный ввод / вывод файла
  • петли обычно медленные, но векторизация быстрая (если вы не знаете синтаксис вектора, изучите его)
  • операции с ядром выполняются очень быстро (например, умножение матрицы, FFT)
  • если вы думаете, что можете сделать что-то быстрее в C / Fortran / etc, вы можете написать MEX-файл
  • существуют коммерческие решения для преобразования matlab в C (Google "Matlab to C"), и они работают
0 голосов
/ 26 сентября 2008

Как уже отмечалось, медленный код Matlab часто является результатом недостаточной векторизации.

Однако иногда даже идеально векторизованный код работает медленно. Тогда у вас есть еще несколько вариантов:

  1. Посмотрите, есть ли какие-либо библиотеки / наборы инструментов, которые вы можете использовать. Обычно они написаны так, чтобы быть очень оптимизированными.
  2. Профилируйте ваш код, найдите узкие места и перепишите их на простом C. Соединить код C (например, DLL) с Matlab легко и описано в документации.
...