Впервые опубликовано в KV.by. Здесь приводится в авторской редакции.

MATLAB появился в конце 1970-х как скриптовый язык и обертка над функциями библиотек линейной алгебры LINPACK и EISPACK. Особенностью MATLAB является то, что базовый (а в ту пору — единственный) тип данных в нем — матрица, а не число. Благодаря этому удалось избавить запись матричных операций от циклов, сделав ее более компактной и похожей на математическую. С другой стороны, использование самых современных на тот момент библиотек обеспечивало высокое быстродействие расчетов. Все это способствовало быстрому росту популярности MATLAB.

*Умножение матрицы на число, записанное разными способами*

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

Как и прежде, у MATLAB «под капотом» самые современные математические библиотеки. Сейчас это: Intel Math Kernel Library (MKL) для операций линейной алгебры и Intel Integrated Performance Primitives Library (IPPL) — для оптимизации обработки изображений. MKL включает в себя, в частности, библиотеки: BLAS, реализующую базовые векторно-матричные операции, и LAPACK — современное развитие LINPACK — содержащую решатели задач линейной алгебры. Поэтому неудивительно, что по скорости выполнения MATLAB обгоняет любой «самодельный» код, реализующий векторно-матричные операции. Также уверенно обходит он и пакеты, использующие другие реализации BLAS и LAPACK.

Дело в том, что MKL и IPPL используют SSE и AVX — наборы инструкций для процессора, которые реализуют параллельные вычисления, в случае, когда нужно выполнить одну и ту же последовательность действий над разными данными (SIMD). Это приводит к существенному росту производительности, причем без каких-либо усилий со стороны пользователя.

Кроме того, MATLAB, вероятно, использует SSE/AVX и в функциях своего ядра, которые реализованы на С. По крайней мере, для разработки пакета MathWorks использует Intel Parallel Studio XE, в состав которого входит компилятор C/C++. Любопытно, что на компьютерах с процессорами AMD MATLAB также использует библиотеки, разработанные в Intel, хотя AMD реализовало свою библиотеку со сходными возможностями — AMD Core Math Library (ACML).

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

*Определение версий используемых MATLAB библиотек с помощью функции version*

Для того чтобы эффективно использовать эти возможности, нужно «векторизовать» программу, т. е. заменить использование циклов операциями над массивом в целом, которые как раз и реализуются быстрыми функциями MATLAB.

Но и циклы не были забыты. В 2003 г. в составе MATLAB (версии 6.5, R13) появился JIT-компилятор. Он анализирует выполняемую программу, транслируя повторяющиеся фрагменты в машинный код. В результате, при последующих повторениях скорость выполнения этих фрагментов значительно возрастает (иногда — до 100 раз), что позволяет сделать некоторые циклы почти столь же быстрыми, как их векторизованные аналоги. Но: для того, чтобы JIT-компилятор можно было успешно применить, код цикла должен удовлетворять определенным требованиям.

Краткую сводку этих требований, а также советов по векторизации программы, можно получить в работе Writing Fast MATLAB Code, а более детальную и свежую информацию — в блоге Undocumented Matlab Яира Альтмана или на страницах его книги “Accelerating MATLAB Performance” — наиболее подробному на сегодняшний день руководству по оптимизации программ MATLAB. Кстати, приведенное выше использование функции version также относится к недокументированным возможностям пакета.

В качестве более дешевой альтернативы MATLABу можно использовать Python c библиотеками NumPy/SciPy и установленной MKL. При этом вместо JIT-компилятора MATLAB применяются Numba или Cython. Многочисленные тесты, результаты которых можно найти в Интернет (например, этот), говорят о том, что MATLAB и связка Python + SciPy выдают весьма близкие по быстродействию результаты, так что на первый план выступают умение программиста и его знание особенностей конкретного пакета.

P.S. Уже после опубликования статьи мне стало известно, что в современном Scilab (v. 5.5) также используется библиотека Intel MKL, так что количество бесплатных альтернатив растет.



Комментарии

comments powered by Disqus