Почему Python не может векторизовать map () или составить список - PullRequest
1 голос
/ 21 сентября 2019

Я не так много знаю о векторизации, но мне интересно понять, почему такой язык, как python, не может обеспечить векторизацию итерируемых элементов через интерфейс библиотеки, так же как он обеспечивает поддержку потоков.Мне известно, что многие методы NumPy векторизованы, но может быть ограниченным необходимость работать с NUMPY для общих вычислений.

В настоящее время я понимаю, что Python не способен векторизовать функции, даже если они соответствуют "SIMD"." шаблон.Например, теоретически не должно ли какое-либо понимание списка или использование функции map() быть векторизованными, потому что они выводят список, который является результатом выполнения той же функции на независимых входах из списка ввода?

При моем понимании niave кажется, что всякий раз, когда я использую map(), теоретически я должен быть в состоянии создать набор инструкций, который представляет функцию;тогда каждый элемент на входе просто должен быть запущен через ту же функцию, которая была скомпилирована.Какова техническая проблема при разработке инструмента, предоставляющего simd_map(func, iterable), который пытается скомпилировать func «точно в срок», а затем получает пакеты ввода из iterable и использует возможности процессора simd для запуска этих пакетов через func()?

Спасибо!

Ответы [ 2 ]

5 голосов
/ 21 сентября 2019

Операция, применяемая map, является произвольным кодом Python.CPython является интерпретатором, а не JIT-компилятором.

CPython может может иметь некоторые стандартные функции C (заранее скомпилированные как часть интерпретатора) для операций SIMD над массивами, ноэто не AFAIK.Несмотря на это, ему пришлось бы оптимизировать поставляемый func, чтобы он мог выполнять распознавание образов, чтобы заметить, что, например, он a[i] = max(a[i], some_value).

Но обычно CPython не сделать это;издержки интерпретатора - огромная проблема для циклического перебора элементов массива. CPython нигде не близок к производительности собственного скалярного цикла, поэтому есть огромные возможности для выигрыша даже без автоматической векторизации. Как и в 200 раз медленнее IIRC.например, Почему побитовые операторы медленнее, чем умножение / деление / по модулю? показывает, что некоторые операции даже не имеют "быстрого пути" для маленьких целых чисел, и что служебных данных достаточно, чтобы сделать & медленнее, чем//, который внутренне использует инструкцию аппаратного деления.

Кроме того, Списки Python не хранятся в виде простых непрерывных массивов int32_t или double, поэтому CPU SIMD не работает в любом случае .Вот почему массивы numpy являются особыми: они хранят значения, такие как массив C примитивных типов.


(Предостережение: я почти не знаю Python и не использую его регулярно. Но я думаю, что знаю достаточно дляэтот ответ будет правильным: это интерпретатор, написанный на языке Си, который не выполняет генерацию собственного машинного кода на лету. Единственные собственные циклы, которые могут выполняться, - это те, которые предварительно скомпилированы как часть интерпретатора, или в NumPyбиблиотеки.)

0 голосов
/ 21 сентября 2019

Вы хотите, чтобы векторизация или JIT-компиляция использовали numba, pypy или cython, но имейте в виду, что скорость достигается за счет гибкости.

numba - это модуль Python, который будет JIT компилировать определенные функции для вас, но он не поддерживает многие виды ввода и barfs для некоторых (многих) конструкций Python.Это действительно быстро, когда работает, но может быть трудно спорить.Он также очень ориентирован на работу с массивами numpy.

pypy - полная замена интерпретатора cpython, который является JIT.Он поддерживает всю спецификацию python, но плохо интегрируется с расширениями, поэтому некоторые библиотеки не будут работать.

cython - это расширение python, которое компилируется в двоичный файл, который будет вести себя как модуль python.Однако он требует от вас использования специального синтаксиса, чтобы воспользоваться преимуществами увеличения скорости, и требует, чтобы вы явно объявляли вещи как ctypes, чтобы реально получить какое-либо преимущество.

Моя рекомендация: используйте pypy, если вы чистый python.(если это работает для вас, это в основном без усилий) Используйте numba, если вам нужно ускорить числовые вычисления, которые numpy не имеет хорошего способа сделать.Используйте Cython, если вам нужна скорость, а другие 2 не работают.

...