Ускорение преобразования Matlab в C ++ - PullRequest
8 голосов
/ 05 августа 2009

У меня есть некоторый код обработки изображений Matlab, который выполняется довольно медленно, и я готов преобразовать его в C / C ++. Я не очень много знаю о том, как работает Matlab и как выполняется код, но мне просто интересно услышать, какие ускорения я могу ожидать. Ясно, что на это влияют многие переменные, но я просто ищу руководство, возможно, из вашего собственного опыта.

Спасибо

Зенна

Ответы [ 7 ]

8 голосов
/ 05 августа 2009

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

То, как я смотрю на Matlab, заключается в том, что каждая исполняемая строка имеет некоторое количество служебных данных. Если вы можете перевести свое решение в форму умножения матрицы или какой-либо другой операции с вектором / матрицей, вы будете страдать только один раз, и она будет незначительной. Тем не менее, с циклами, вы переносите накладные расходы каждый раз, когда цикл повторяется. Кроме того, большинство функций обработки изображений Matlab просто обращаются к оптимизированным библиотекам, поэтому не пытайтесь воссоздать их, если не знаете наверняка, где их можно улучшить.

Я обнаружил, что лучший подход - использовать комбинацию C и Matlab. Я использую Matlab, когда операция может быть легко векторизована (в терминах векторных / матричных операций). Это может означать приход к решению под другим углом, чем тот, который кажется наиболее простым. Кроме того, трудно превзойти построение графиков и визуализацию Matlab, поэтому я бы определенно не перешел на полностью C / C ++ решение, если у вас нет плана, как отображать с C / C ++ (если это является частью вашего проекта).

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

4 голосов
/ 05 августа 2009

Это действительно зависит от качества вашего кода Matlab и от того, что вы делаете. Идиоматический код Matlab, написанный экспертом Matlab, будет непростой задачей, особенно если вы не гуру оптимизации и просто ожидаете ускорения из-за смены языка. Например, я обнаружил, что даже некоторые из наиболее уважаемых библиотек FFT на основе C не подходят для FFT Matlab.

Тем не менее, сравнивая плохо написанную программу на Matlab со средне написанной программой на c ++, я бы сказал, что вы смотрите на порядок в моем опыте.

3 голосов
/ 05 августа 2009

Короткий ответ на вопрос о том, какие ускорения вы можете получить: «Это зависит».

Matlab - интерпретатор, поэтому в целом он намного медленнее, чем собственный код на C ++. Однако многие функции Matlab хорошо оптимизированы, и последние версии включают JIT. Таким образом, вам придется решить, следует ли переписать весь ваш код Matlab в C, переписать только критические части или оптимизировать сам код Matlab для более быстрой работы.

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

1 голос
/ 07 августа 2009

Я экспортировал подпрограмму matlab в c ++ и скомпилировал с Visual Studio C ++ как mex. Ускорение было в 10 раз. И если бы я использовал многоядерные процессоры, то я бы, вероятно, также в 3 раза больше скорости.

Если у вас есть уклоны на склонах и вы что-то делаете с отдельными компонентами матрицы, что-то вроде y (m, n) = x (m) * a - x (m-1), и это для склонов, тогда вы будете иметь хорошую скорость.

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

1 голос
/ 05 августа 2009

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

Однако, если вы обнаружите, что ваш код состоит из множества циклов (например, циклически повторяющихся по всем пикселям на изображении), он будет невероятно медленным, а векторизация может увеличить скорость в 100 раз или более.

Если ваш код очень сложно сделать «правильно» в MATLAB, тогда переход на C может быть приемлемым вариантом. Я делал проект по компьютерному зрению в школе (3D точечная реконструкция), который ясно показал это. Когда наш проект, который был реализован на C ++ и OpenCV, закончил вычисление, один из проектов других групп едва загрузил изображения. Они были написаны в MATLAB. Мы никогда не рассчитывали это, но мое предположение заключается в том, что наша версия работала примерно в 10 раз быстрее.

Но опять же, их код MATLAB, вероятно, вообще не был оптимизирован. Так что это не очень полезно в качестве эталона.

1 голос
/ 05 августа 2009

Например, Matlab использует библиотеку FFTW для реализации алгоритмов FFT. Производительность этой библиотеки почти невозможно превзойти. Единственное, что я знаю, сравнимо это библиотека Math Kernel Library (MKL), но она коммерческая. Поэтому прежде всего я бы предложил использовать все математические библиотеки, которые вы можете найти. Матлаб делает это за кулисами.

Это правда, что иногда трудно победить матлаба. Но дело в том, что профилировщик Matlab не всегда дает вам достаточно информации о том, как улучшить ваш код. Вы знаете, что некоторые методы matlab занимают большую часть времени, но вы не всегда знаете, есть ли способы улучшить производительность, вызывая их по-другому, потому что этот метод является черным ящиком.

В C / C ++ у вас есть такие инструменты, как valgirnd , которые позволяют вам проверять, даже если ассемблер генерирует компилятор, и таким образом вы можете помочь компилятору улучшить этот код, например, для встроенного метода. Но опять же, Matlab использует закулисные профессиональные математические библиотеки, и если большая часть времени тратится на эти библиотеки, когда вы выполняете свой код Matlab, производительность трудно улучшить.

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

0 голосов
/ 06 августа 2009

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

Убедитесь, что вы пытаетесь свести к минимуму количество раз, когда данные передаются между MATLAB и C ++. Если вы отправляете большие массивы данных одним большим скоплением, это, скорее всего, будет быстрым. В противном случае, если вы выполняете много передач данных назад и вперед, даже если ваша программа на C ++ работает быстро, вы можете потерять преимущество в скорости при преобразовании данных.

Я бы также посмотрел ваши алгоритмы и подумал об использовании Java. Очень удобно вызывать пользовательский код Java из MATLAB, так как MATLAB уже работает на JRE. Я был очень впечатлен скоростью передачи больших массивов данных между функциями MATLAB и моим собственным кодом Java. Несколько лет назад я рассматривал реализацию алгоритма на прямом C ++ (с использованием MEX или чего-либо еще) для ускорения работы с MATLAB, и это выглядело как кошмар для работы со всеми структурами данных. Вместо этого я использовал COM / ActiveX, потому что работал на компьютере с Windows, и интерфейс был намного проще.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...