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

StackOverflow https://stackoverflow.com/questions/137011

Вопрос

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

Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top