Почему я не вижу значительного ускорения при использовании компилятора MATLAB?

#c #performance #matlab #matlab-compiler

Вопрос:

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

Комментарии:

1.Вы пробовали профилировать свой код matlab? mathworks.com/access/helpdesk/help/techdoc/index.html?/access/…weizmann.ac.il/matlab/techdoc/matlab_prog/ch8_pr18.html

2. Можете ли вы привести несколько примеров того, что работает медленно?

3. Не могли бы вы привести пример? Как вы определяете медленное? Вы пробовали векторизировать петли?

4. Сначала определите медленные части вашего кода (например, с помощью профилирования), прежде чем выбрать инструмент для его исправления (новый язык/компилятор).

5. Надеюсь, еще один комментарий о предоставлении медленного кода заставит вас увидеть комментарии и прочитать их.

Ответ №1:


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

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

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

Более старые версии компилятора работали по-другому, и в определенных ситуациях могло произойти ускорение. Для решения математических задач перейдите по ссылке

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

Ответ №2:

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

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

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

Ответ №3:

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

Это в равной степени относится ко всем динамическим языкам, ориентированным на массивы: Язык данных Perl, Числовой Python, MATLAB/Октава и т. Д. В какой-то степени это даже верно для скомпилированного кода на C и FORTRAN: специально разработанные библиотеки векторизации обычно используют тщательно закодированные вручную внутренние циклы и инструкции SIMD (например, MMX, SSE, AltiVec).

Ответ №4:

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

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

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

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

Ответ №5:

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

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

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

Ответ №6:

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

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

Ответ №7:

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

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

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

  • операции на уровне битов выполняются очень медленно
  • ввод-вывод файлов происходит медленно
  • циклы, как правило, медленные, но векторизация выполняется быстро (если вы не знаете синтаксиса векторов, изучите его)
  • основные операции выполняются очень быстро (например, умножение матрицы, fft)
  • если вы думаете, что можете сделать что-то быстрее в C/Fortran/etc, вы можете написать файл MEX
  • существуют коммерческие решения для преобразования matlab в C (google «matlab в c»), и они работают

Ответ №8:

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

Встроенный Matlab — это подмножество Matlab. Он не поддерживает массивы ячеек, графику, приложения динамического размера или некоторые режимы матричного адресирования. Для переноса на встроенный Matlab может потребоваться значительное усилие.

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

Ответ №9:

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

Если узким местом является матричная математика, вы, вероятно, не добьетесь ничего лучшего… ЗА исключением одной большой ошибки-это выделение массива. например, если у вас есть цикл:

 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 я не думаю, что когда-нибудь вернусь к этому.

Ответ №10:

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

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

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

Ответ №11:

Под компилятором Matlab вы, вероятно, подразумеваете команду mcc, которая немного ускоряет код, обходя интерпретатор Matlab. Что значительно ускорит код MAtlab (в 50-200 раз), так это использование фактического кода C, скомпилированного командой mex.