Pull to refresh

Numpy и многопроцессорность

Reading time 4 min
Views 21K
Сейчас уже многие используют библиотеку numpy в своих python-программах, поскольку она заметно ускоряет работу с данными и выполнение математических операций. Однако во многих случаях numpy работает в разы медленнее, чем она может… потому что использует только один процессор, хотя могла бы использовать все, что у вас есть.

Дело в том, что для выполнения многих операций numpy вызывает функции из библиотеки линейной алгебры. Вот в ней-то обычно и кроется проблема. К счастью, все довольно легко исправимо.

Итак, возможно три ситуации:

  • у вас не установлены никакие библиотеки линейной алгебры и тогда numpy использует встроенную библиотеку, и она, надо сказать, весьма медленная;
  • у вас уже установлены классические библиотеки типа ATLAS и BLAS, и они умеют использовать только один процессор;
  • у вас установлена современная библиотека OpenBLAS, MKL и им подобные.

Проведем простой тест. Запустите вот эту программу:

import numpy as np
size = 10000
a = np.random.random_sample((size, size))
b = np.random.random_sample((size, size))
n = np.dot(a,b)

После чего, если работаете в Linux, то запустите top, а если вы работаете в Windows, зайдите на вкладку в “Быстродействие” в диспетчере задач (вызывается по Ctrl+Shift+Esc)… Если top показывает загруженность на уровне 100%, а индикатор “Загрузка ЦП” на вкладке “Быстродействие”, наоборот, показывает значение многократно ниже 100%, значит вычислениями занято лишь одно ядро — и эта статья для вас. Те, у кого задействованы все процессоры, могут радоваться — у них все в порядке — и дальше можно не читать.

Решение для Windows

Теоретически, можно, конечно, найти исходники библиотек, перекомпилировать их и пересобрать numpy. Я даже слышал, что кто-то писал, что он видел людей, которые говорили, что им это удалось… В общем, самый простой способ — это установить научный дистрибутив Python, например, Anaconda или Canopy. В дистрибутив входит не только python и numpy, но и целая куча полезных библиотек для расчетов и визуализации.

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

Решение для Linux

На самом деле вы также можете установить готовый дистрибутив Anaconda, Canopy или что-то другое сразу со всеми библиотеками. Но если предпочитаете собирать своими руками, то читайте дальше — там есть все рецепты.

Проверка библиотек


Как вы помните, возможны два варианта:

  • у вас установлены “олдскульные” (или “устаревшие”, кому как нравится) библиотеки (например, ATLAS);
  • у вас не установлены библиотеки, и numpy использует встроенную библиотеку (которая еще медленнее)

Если у вас стоит свежая версия numpy (>1.10), то, зайдя в каталог, куда установлен numpy (обычно это /usr/local/lib/python2.7/dist-packages/numpy, но в зависимости от версии Linux и Python путь может меняться) и выполните следующие команды в консоли:

cd core
ldd multiarray.so

В более ранних версиях numpy библиотеки multiarray.so нет, зато есть _dotblas.so:

ldd _dotblas.so

Вывод команды ldd покажет вам, использует ли numpy сторонние библиотеки линейной алгебры.

linux-vdso.so.1 =>  (0x00007fffe58a2000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8adbff4000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f8adbdd6000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8adba10000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8adc68c000)

Если в листинге вы не видите libblas.so, значит ваша numpy использует свою внутреннюю библиотеку. Если видите, значит у вас стоит ATLAS или BLAS.

В любом случае сначала вам нужна правильна библиотека линейной алгебры.

Установка OpenBLAS


OpenBLAS — хорошая библиотека алгоритмов и функций линейной алгебры, которые лежат в основе современных методов анализа данных и машинного обучения.

Прежде всего вам потребуется компилятор Фортрана, поскольку OpenBLAS не совместим со стандартным компилятором g77.

sudo apt-get install gfortran

Загрузите OpenBLAS с github’а (предварительно вернувшись в подходящий для установки каталог):

git clone https://github.com/xianyi/OpenBLAS.git

Теперь зайдите в каталог и запустите сборку:

cd OpenBLAS
make FC=gfortran

Когда компиляция и сборка успешно завершатся, установите библиотеку.

sudo make install

По умолчанию, библиотека будет установлена в /opt/OpenBLAS. Если вы хотите установить ее в другое место, запустите make install с ключом PREFIX:

sudo make install PREFIX=/your/preferred/location

Переназначение библиотек


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

sudo update-alternatives --install /usr/lib/libblas.so.3 libblas.so.3 \
	/opt/OpenBLAS/lib/libopenblas.so 50

После этого OpenBLAS по умолчанию станет библиотекой линейной алегбры не только для numpy, а вообще для всех ваших программ и библиотек.

И снова запустите тест, чтобы увидеть, как у вас при вычислениях теперь задействованы все процессоры.

Собираем правильный numpy


Если у вас numpy работал на встроенной библиотеке, то вам придется его пересобрать, чтобы он подхватил только что установленный OpenBLAS.

Сначала избавьтесь от дефектной библиотеки:

sudo pip uninstall numpy

После чего создайте в домашнем каталоге файл .numpy-site.cfg следующего содержания:

[default]
include_dirs = /opt/OpenBLAS/include
library_dirs = /opt/OpenBLAS/lib

[openblas]
openblas_libs = openblas
include_dirs = /opt/OpenBLAS/include
library_dirs = /opt/OpenBLAS/lib

[lapack]
lapack_libs = openblas

[atlas]
atlas_libs = openblas
libraries = openblas

Если вы ранее выбрали нестандартное расположение для OpenBLAS, то измените пути в файле. А теперь установите numpy заново:

sudo pip install numpy

Когда компиляция и установка завершатся, запустите начальный тест, чтобы убедиться, что теперь процессоры не простаивают. Вот и все.
Tags:
Hubs:
+20
Comments 14
Comments Comments 14

Articles