Как работает векторный код MATLAB "под капотом"?

Я понимаю, как использование векторизации на языке, таком как MATLAB, ускоряет выполнение кода, устраняя накладные расходы на поддержание переменной цикла, но как векторизация действительно имеет место в коде сборки/машины? Я имею в виду, что где-то еще должна быть петля, верно?

Ответ 1

Концепция векторизации Matlab полностью отличается от концепции векторных инструкций, например SSE. Это распространенное недоразумение между двумя группами людей: программистами Matlab и программистами C/asm. "Векторизация Matlab", как правило, используется только об экспрессии петель в виде (векторов) матричных индексов, а иногда и о написании вещей в терминах основных матричных/векторных операций (BLAS), вместо того, чтобы писать сам цикл. "Векторизованный" код Matlab не обязательно выражается в виде векторизованных инструкций ЦП. Рассмотрим следующий код:

A = rand(1000);
B = (A(1:2:end,:)+A(2:2:end,:))/2;

Этот код вычисляет средние значения для двух смежных строк матрицы. Это "векторизованное" выражение matlab. Однако, поскольку matlab хранит матрицы по столбцам (столбцы смежны в памяти), эта операция не тривиально изменяется на операции с векторами SSE: поскольку мы выполняем операции по строкам, данные, которые необходимо загрузить в векторы, не сохраняются смежно в памяти.

Этот код с другой стороны

A = rand(1000);
B = (A(:,1:2:end)+A(:,2:2:end))/2;

может воспользоваться инструкциями SSE и инструкциями по потоку, поскольку мы работаем с двумя соседними столбцами за раз.

Итак, векторизация Matlab 'не эквивалентна использованию инструкций вектора ЦП. Это просто слово, используемое для обозначения отсутствия цикла, реализованного в MATLAB. Чтобы добавить к путанице, иногда люди даже используют это слово, чтобы сказать, что какой-то цикл реализован с помощью встроенной функции , такой как arrayfun или bsxfun. Что еще более вводит в заблуждение, поскольку эти функции могут значительно медленнее, чем встроенные петли matlab. Как сказал Робинс, в настоящее время не все петли в Matlab медленны, хотя вам нужно знать, когда они работают, и когда они этого не делают.

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

Ответ 2

Да, есть еще петля. Но он может зацикливаться непосредственно в скомпилированном коде. Циклы в Fortran (на которых первоначально была основана Matlab) C или С++ не являются по своей сути медленными. То, что они медленны в Matlab, является свойством динамической среды выполнения (они также медленнее работают на других динамических языках, таких как Python).

Так как Matlab представила производительность цикла компилятора Just-In-Time, на самом деле резко увеличилась - поэтому старые рекомендации по предотвращению циклов менее важны с недавними версиями, чем когда-то были.