Компромисс между производительностью - когда MATLAB лучше / медленнее, чем C / C ++

34

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

Когда я делаю простые вычисления, такие как montecarlo-осреднение выборки гауссовских выборок или так, я вижу, что нет большой разницы между реализацией С++ или реализацией MATLAB, иногда на самом деле MATLAB выполняет бит лучше во времени.

Когда я перехожу к симуляции большего масштаба с тысячами строк кода, медленно появляется реальное изображение. Симуляции на С++ показывают превосходную производительность, такую ​​как 100x лучше во временной сложности, чем эквивалентная реализация MATLAB.

Код на С++ в большинстве случаев довольно много серийный, и оптимизация hi-fi не выполняется явно. Принимая во внимание, что, согласно моему осознанию, MATLAB по своей сути делает большую оптимизацию. Это проявляется, например, когда я пытаюсь создать огромный кусок случайных выборок, где, поскольку эквивалент в С++ с использованием некоторой библиотеки, такой как IT ++/GSL/Boost, выполняется относительно медленнее (используемый алгоритм - то же самое, а именно mt19937).

Мой вопрос - просто знать, есть ли более простой компромисс между MATLAB/С++ в производительности. Это похоже на то, что люди говорят: "Когда бы вы ни были, C/С++ лучше" (часто встречающийся). В другой перспективе: "Что такое MATLAB для удобства, кроме комфорта?"

Кстати, я не вижу здесь значения эффективности кодирования, думая об одном и том же программисте в обоих случаях. Кроме того, я думаю, что другие альтернативы, такие как python, R, здесь не актуальны. Но зависимость от конкретных библиотек, которые мы используем, должна быть интересной.

[Я являюсь студентом PhD в теории кодирования в системах связи. Я выполняю симуляции с использованием matlab/С++ все время и имею разумный опыт кодирования нескольких 10K строк в обоих случаях]

  • 1
    Ну, с точки зрения производительности, matlab лучше, когда вы знаете, как его кодировать, и не знаете, как кодировать c ++, c ++ лучше в остальное время.
  • 2
    Я сделал переводы с Matlab на C ++. Типичное ожидание для «нормального» кода Matlab было для C ++ быть в 20 раз быстрее.
Показать ещё 4 комментария
Теги:
performance

9 ответов

72

Я использую Matlab и С++ около 10 лет. Для всех численных алгоритмов, реализованных для моих исследований, я всегда начинаю с прототипирования с помощью Matlab, а затем переводим проект на С++, чтобы получить улучшение производительности от 10x до 100x (я не шучу). Конечно, я сравниваю оптимизированный код С++ с полностью векторизованным кодом Matlab. В среднем улучшение составляет около 50 раз.

Есть много тонкостей за обоими двумя языками программирования, а следующие недоразумения:

  • Matlab - это script язык, но С++ скомпилирован

    Matlab использует JIT-компилятор для перевода вашего script в машинный код, вы можете улучшить свою скорость максимум на 1,5-2, используя компилятор, который предоставляет Matlab.

  • Код Matlab может быть полностью векторизован, но вы должны оптимизировать свой код вручную в С++

    Полностью векторный код Matlab может вызывать библиотеки, написанные на С++/C/Assembly (например, Intel MKL). Но простой С++-код может быть разумно векторизован современными компиляторами.

  • Панели инструментов и процедуры, которые Matlab обеспечивает, должны быть очень хорошо настроены и должны иметь разумную производительность

    Нет. В отличие от подпрограмм линейной алгебры, производительность, как правило, плохая.

Причины, по которым вы можете получить производительность 10x ~ 100x в С++ по сравнению с векторизованным кодом Matlab:

  • Вызов внешних библиотек (MKL) в Matlab требует времени.

  • Память в Matlab динамически распределяется и освобождается. Например, умножение малых матриц:
    A = B*C + D*E + F*G
    требует, чтобы Matlab создавал 2 временных матрицы. И в С++, если вы выделите свою память перед рукой, вы создадите NONE. А теперь представьте, что вы зацикливаете это утверждение на 1000 раз. Другое решение в С++ предоставляется ссылкой С++ 11 Rvalue. Это одно из самых больших улучшений в С++, теперь код С++ может быть таким же быстрым, как обычный C-код.

  • Если вы хотите выполнять параллельную обработку, модель Matlab является многопроцессорной, а путь С++ - многопоточным. Если у вас есть много небольших задач, которые нужно распараллелить, С++ обеспечивает линейное усиление до многих потоков, но у вас может быть отрицательное усиление производительности в Matlab.

  • Вы передаете большие объекты, кусок памяти по ссылке в С++, но это довольно сложно в Matlab.

  • Векторизация в С++ включает использование intrinsics/assembly, а иногда SIMD-векторизация возможна только в С++.

  • Указатели делают чудеса на С++. Обработка изображений с помощью двух матриц A и B: в Matlab она включает в себя 3-ю матрицу и требует 3 * N * N операций элементарной копии. Но в С++ это делается указателями с нулевой стоимостью.

  • В С++ опытный программист может полностью избежать пропусков кэш-памяти L2 и даже пропустить кеш-память L1, тем самым подталкивая CPU к теоретическому пределу пропускной способности. Производительность Matlab может отставать от С++ в 10 раз по этой причине.

  • В С++ команды с интенсивным вычислением иногда могут быть сгруппированы в соответствии с их задержками (код тщательно связан с сборкой или встроенными функциями) и зависимостями (большая часть времени выполняется автоматически с помощью компилятора или аппаратного обеспечения ЦП), так что теоретические IPC (инструкции за такт) может быть достигнуто, а CPU-трубопроводы заполнены.

Однако время разработки в С++ также является фактором 10x по сравнению с Matlab!

Причины, по которым вам следует использовать Matlab вместо С++:

  • Визуализация данных. Я думаю, что моя карьера может продолжаться без С++, но я не смогу выжить без Matlab только потому, что она может генерировать красивые сюжеты!

  • Низкая эффективность, но математически надежные встроенные подпрограммы и панели инструментов. Сначала получите правильный ответ, а затем поговорите об эффективности. Люди могут делать тонкие ошибки в С++ (например, неявно преобразовать double в int) и получить правильные результаты.

  • Выскажите свои идеи и представьте свой код своим коллегам. Код Matlab намного проще читать и намного короче, чем С++, а код Matlab можно корректно исполнить без компилятора. Я просто отказываюсь читать код С++ других людей. Я даже не использую научные библиотеки С++ GNU, потому что качество кода не гарантируется. Для исследователя/инженера опасно использовать библиотеку С++ в качестве черного ящика и принимать правильную точность. Даже для коммерческих библиотек C/С++ я помню, что у компилятора Intel была знак ошибка в sin()функции в прошлом году и проблемы с числовой точностью также произошли в MKL.

Последнее, но не менее важное:

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

  • 4
    Это прекрасное резюме. И это сделало меня слишком любопытным, чтобы выяснить, кто этот удивительный доктор философии из Корнелла, но «Судя по всему, этот пользователь предпочитает держать в тайне о них». Уже более 2 лет с тех пор, как я задал этот вопрос. Это не проблема, уважать частную жизнь. Ура!
  • 1
    Спасибо! Я очень рад помочь и поделиться своими усвоенными уроками прошлого.
Показать ещё 6 комментариев
8

По моему опыту (несколько лет компьютерного видения и обработки изображений на обоих языках) нет простого ответа на этот вопрос, так как производительность Matlab сильно зависит (и намного больше, чем производительность С++) от вашего стиля кодирования.

Как правило, Matlab обертывает классические библиотеки линейной алгебры на основе С++/Fortran. Итак, что-нибудь вроде x = A\b будет очень быстрым. Кроме того, Matlab делает хорошую работу по выбору наиболее эффективного решения для этих проблем, поэтому для x = A\b Matlab будет смотреть на размер ваших матриц и выбирать соответствующие низкоуровневые процедуры.

Matlab также сияет в обработке данных больших матриц, если вы "вектурируете" свой код, т.е. если вы избегаете циклов for и используете массивы индексов или логические массивы для доступа к вашим данным. Этот материал сильно оптимизирован.

Для других подпрограмм некоторые из них написаны в коде Matlab, а другие указывают на реализацию C/С++ (например, материал Delaunay). Вы можете проверить это самостоятельно, набрав edit some_routine.m. Это открывает код, и вы видите, все ли это Matlab или просто оболочка для компилируемого компилятора.

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

  • 0
    Спасибо за ответ. Но, учитывая всю мудрость уровня оптимизации Matlab и Fortran, почему Matlab должен быть медленнее!
  • 0
    Я имею в виду, разве это не напрасная попытка оптимизации на уровне сборки, если вы не видите каких-либо улучшений? Кроме того, хотя я понимаю вашу точку зрения, «сильно зависит от вашего стиля кодирования» это то, что требует некоторой проработки. Я бы на самом деле попросил рассмотреть разумную эффективность программирования с обеих сторон, которая все еще имеет 100-кратный диапазон различий.
Показать ещё 3 комментария
4

Matlab отлично справляется с линейной алгеброй и операциями с массивами/матрицами, поскольку они, похоже, делали некоторые дополнительные оптимизации для основных операций - если вы хотите победить Matlab, вам понадобится аналогичная оптимизированная библиотека BLAS/LAPACK.

Как интерпретируемый язык, Matlab теряет время всякий раз, когда вызывается функция Matlab из-за внутренних накладных расходов, что традиционно означает, что петли Matlab были медленными. Это несколько облегчилось в последние годы благодаря значительному улучшению компилятора JIT (поиск примеров "производительности" на Matlab на SO для примеров). Вследствие накладных расходов функции все функции Matlab, которые не были реализованы в C/С++ за кулисами (вызов edit functionName, чтобы увидеть, написан ли он в Matlab), рискуют быть медленнее, чем аналоги C/С++.

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

4

Будучи студенткой PhD и 10-летним пользователем Matlab, я рад поделиться своим POV:

Matlab - отличный инструмент для разработки и прототипирования алгоритмов, особенно при работе с графическими интерфейсами, анализе высокого уровня (Frequency Domain, LS Optimization и т.д.): быстрое кодирование, мощный синтаксис (подумайте о [], {}, и т.д.).

Как только ваша цепочка обработки будет более стабильной и определена, а данные будут расти, перейдите в C/С++.

Основной предел Matlab возрастает при рассмотрении его языка script -like: если вы избегаете любого cicle (используя arrayfun, cellfun или другие матричные процедуры), показатели высоки, так как вызываемая подпрограмма снова находится в C/С++.

3

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

Итак, мой вывод состоит в том, что вам нужно измерить производительность обеих программ, чтобы получить ответ. Но тогда вы сравниваете свои две реализации, а не Matlab и С++ вообще.

3

Я думаю, что вы можете рассмотреть разницу в четырех снах, по крайней мере.

  • Скомпилированный vs Интерпретированный
  • Сильно типизированный vs Динамически типизированный
  • Производительность против быстрого прототипирования
  • Специальная сила

Для 1-3 можно легко обобщить на сравнение между двумя семействами языков программирования.

Для 4, MATLAB оптимизирован для операций с матрицей. Поэтому, если вы можете векторизовать больше кода в MATLAB, производительность может быть значительно увеличена. И наоборот, если требуется много loops, не стесняйтесь использовать C++ или создать файл mex.

В конце концов, это сложный вопрос.

2

Я видел улучшение скорости 5,5х при переключении с MATLAB на С++. Это было для робота-контроллера - множество циклов и оде. Я потратил много часов, пытаясь оптимизировать код MATLAB, практически не оптимизируя С++ (я уверен, что он мог бы быть быстрее на 10 раз с меньшими усилиями).

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

2

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

Если вы используете прямые С++ (т.е. нет матричных библиотек), может потребоваться намного больше времени, чтобы написать код на С++, эквивалентный коду Matlab (например, не может быть смысла тратить 10 часов на запись кода на С++, который только выполняется на 10 секунд быстрее, по сравнению с программой Matlab, на которую потребовалось 5 минут).

Однако существуют специальные библиотеки С++, такие как Armadillo, которые предоставляют Matlab-подобный API. Это может быть полезно для написания критического кода производительности, который можно вызывать из Matlab, или для преобразования кода Matlab в "реальные" программы.

1

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню