Подтвердить что ты не робот

Многопоточность blas в python/numpy

Я пытаюсь реализовать большое количество матрично-матричных умножений в Python. Первоначально я предполагал, что NumPy будет автоматически использовать мои потоковые библиотеки BLAS, поскольку я построил их для этих библиотек. Однако, когда я смотрю top или что-то еще, похоже, что код не использует потоковую передачу вообще.

Любые идеи, что не так, или что я могу сделать, чтобы легко использовать производительность BLAS?

4b9b3361

Ответ 1

Не все NumPy использует BLAS, только некоторые функции - в частности dot(), vdot() и innerproduct() и несколько функций из модуля numpy.linalg. Также обратите внимание, что многие операции NumPy ограничены пропускной способностью памяти для больших массивов, поэтому оптимизированная реализация вряд ли даст какое-либо улучшение. Может ли многопоточность обеспечить лучшую производительность, если вы ограничены пропускной способностью памяти, сильно зависит от вашего оборудования.

Ответ 2

Я уже разместил это в другом потоке, но я думаю, что он лучше подходит в этом:

ОБНОВЛЕНИЕ (30.07.2014):

Я снова запускаю тест на нашем новом HPC. Как аппаратное обеспечение, так и программный стек изменились с установки в исходном ответе.

Я помещал результаты в таблицу google (также содержит результаты исходного ответа).

Оборудование

Наш HPC имеет два разных узла с процессорами Intel Sandy Bridge и один с новыми процессорами Ivy Bridge:

Sandy (MKL, OpenBLAS, ATLAS):

  • CPU: 2 x 16 Intel (R) Xeon (R) E2560 Sandy Bridge @2,00 ГГц (16 ядер)
  • ОЗУ: 64 ГБ

Ivy (MKL, OpenBLAS, ATLAS):

  • CPU: 2 x 20 Intel (R) Xeon (R) E2680 V2 Ivy Bridge @2,80 ГГц (20 ядер, с HT = 40 ядер)
  • ОЗУ: 256 ГБ

Программное обеспечение

Программный стек предназначен для обоих узлов sam. Вместо GotoBLAS2 используется OpenBLAS, а также есть многопоточный ATLAS BLAS, который настроен на 8 потоков (hardcoded).

  • ОС: Suse
  • Компилятор Intel: ictce-5.3.0
  • Numpy: 1.8.0
  • OpenBLAS: 0.2.6
  • ATLAS:: 3.8.4

Контрольная точка Dot-Product

Контрольный код такой же, как и ниже. Однако для новых машин я также использовал контрольный показатель для размеров матрицы 5000 и 8000.
В приведенной ниже таблице приведены результаты тестов исходного ответа (переименованные: MKL → Nehalem MKL, Netlib Blas → Nehalem Netlib BLAS и т.д.)

Matrix multiplication (sizes=[1000,2000,3000,5000,8000])

Производительность с одной резьбой: single threaded performance

Многопоточная производительность (8 потоков): multi-threaded (8 threads) performance

Потоки против размера матрицы (Ivy Bridge MKL): Matrix-size vs threads

Benchmark Suite

benchmark suite

Производительность с одной резьбой: enter image description here

Производительность с несколькими потоками (8 потоков): enter image description here

Заключение

Новые результаты тестов аналогичны тем, что были в исходном ответе. OpenBLAS и MKL выполняются на одном уровне, за исключением теста Собственное значение. Тест Собственные значения работает достаточно хорошо на OpenBLAS в режиме с одним потоком. В многопоточном режиме производительность хуже.

Таблица "Матрица по сравнению с диаграммой потоков" также показывает, что хотя MKL, а также OpenBLAS обычно хорошо масштабируются с количеством ядер/потоков, это зависит от размера матрицы. Для небольших матриц добавление большего количества ядер не улучшит производительность.

Также наблюдается увеличение производительности примерно на 30% от Sandy Bridge до Ivy Bridge, что может быть связано с более высокой тактовой частотой (+ 0,8 ГГц) и/или лучшей архитектурой,


Оригинальный ответ (04.10.2011):

Некоторое время назад мне приходилось оптимизировать вычисления/алгоритмы линейной алгебры, написанные на питоне с использованием numpy и BLAS, поэтому я тестировал/тестировал различные конфигурации numpy/BLAS.

В частности, я тестировал:

  • Numpy с ATLAS
  • Numpy с GotoBlas2 (1.13)
  • Numpy с MKL (11.1/073)
  • Numpy with Accelerate Framework (Mac OS X)

Я выполнил два разных теста:

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

Вот мои результаты:

Машины

Linux (MKL, ATLAS, No-MKL, GotoBlas2):

  • ОС: Ubuntu Lucid 10.4 64 бит.
  • CPU: 2 x 4 Intel (R) Xeon (R) E5504 @2,00 ГГц (8 ядер)
  • ОЗУ: 24 ГБ
  • Компилятор Intel: 11.1/073
  • Scipy: 0.8
  • Numpy: 1.5

Mac Book Pro (ускорение):

  • ОС: Mac OS X Snow Leopard (10.6)
  • CPU: 1 Intel Core 2 Duo 2.93 Ghz (2 ядра)
  • ОЗУ: 4 ГБ
  • Scipy: 0.7
  • Numpy: 1.3

Mac Server (ускорение):

  • ОС: Mac OS X Snow Leopard Server (10.6)
  • CPU: 4 X Intel (R) Xeon (R) E5520 @2.26 Ghz (8 ядер)
  • ОЗУ: 4 ГБ
  • Scipy: 0.8
  • Numpy: 1.5.1

Тест производительности продукта

Код:

import numpy as np
a = np.random.random_sample((size,size))
b = np.random.random_sample((size,size))
%timeit np.dot(a,b)

Результаты

    System        |  size = 1000  | size = 2000 | size = 3000 |
netlib BLAS       |  1350 ms      |   10900 ms  |  39200 ms   |    
ATLAS (1 CPU)     |   314 ms      |    2560 ms  |   8700 ms   |     
MKL (1 CPUs)      |   268 ms      |    2110 ms  |   7120 ms   |
MKL (2 CPUs)      |    -          |       -     |   3660 ms   |
MKL (8 CPUs)      |    39 ms      |     319 ms  |   1000 ms   |
GotoBlas2 (1 CPU) |   266 ms      |    2100 ms  |   7280 ms   |
GotoBlas2 (2 CPUs)|   139 ms      |    1009 ms  |   3690 ms   |
GotoBlas2 (8 CPUs)|    54 ms      |     389 ms  |   1250 ms   |
Mac OS X (1 CPU)  |   143 ms      |    1060 ms  |   3605 ms   |
Mac Server (1 CPU)|    92 ms      |     714 ms  |   2130 ms   |

Dot product benchmark - chart

Benchmark Suite

Код:
Дополнительную информацию о наборе тестов см. В здесь.

Результаты:

    System        | eigenvalues   |    svd   |   det  |   inv   |   dot   |
netlib BLAS       |  1688 ms      | 13102 ms | 438 ms | 2155 ms | 3522 ms |
ATLAS (1 CPU)     |   1210 ms     |  5897 ms | 170 ms |  560 ms |  893 ms |
MKL (1 CPUs)      |   691 ms      |  4475 ms | 141 ms |  450 ms |  736 ms |
MKL (2 CPUs)      |   552 ms      |  2718 ms |  96 ms |  267 ms |  423 ms |
MKL (8 CPUs)      |   525 ms      |  1679 ms |  60 ms |  137 ms |  197 ms |  
GotoBlas2 (1 CPU) |  2124 ms      |  4636 ms | 147 ms |  456 ms |  743 ms |
GotoBlas2 (2 CPUs)|  1560 ms      |  3278 ms | 116 ms |  295 ms |  460 ms |
GotoBlas2 (8 CPUs)|   741 ms      |  2914 ms |  82 ms |  262 ms |  192 ms |
Mac OS X (1 CPU)  |   948 ms      |  4339 ms | 151 ms |  318 ms |  566 ms |
Mac Server (1 CPU)|  1033 ms      |  3645 ms |  99 ms |  232 ms |  342 ms |

Benchmark suite - chart

Установка

Установка MKL включала установку полного набора компиляторов Intel, который довольно прост. Однако из-за некоторых ошибок/проблем настройка и компиляция numpy с поддержкой MKL была немного сложной.

GotoBlas2 - это небольшой пакет, который можно легко скомпилировать как общую библиотеку. Однако из-за ошибки вам необходимо заново создать общую библиотеку после ее создания, чтобы использовать ее с numpy.
В дополнение к этому зданию он для нескольких целевых платформ не работал по какой-то причине. Поэтому мне пришлось создать файл .so для каждой платформы, для которой я хочу иметь оптимизированный файл libgoto2.so.

Если вы установите numpy из репозитория Ubuntu, он автоматически установит и настроит numpy для использования ATLAS. Установка ATLAS из источника может занять некоторое время и потребует дополнительных шагов (fortran и т.д.).

Если вы установите numpy на машине Mac OS X с Fink или Mac-портами, он либо настроит numpy на использование ATLAS, либо Apple Accelerate Framework. Вы можете проверить, запустив ldd в файле numpy.core._dotblas или вызвав numpy.show_config().

Выводы

MKL лучше всего отслеживается GotoBlas2.
В тесте собственное значение GotoBlas2 работает на удивление хуже ожидаемого. Не знаю, почему это так. Apple Accelerate Framework работает очень хорошо, особенно в однопоточном режиме (по сравнению с другими реализациями BLAS).

Оба GotoBlas2 и MKL очень хорошо масштабируются с количеством потоков. Поэтому, если вам приходится иметь дело с большими матрицами, запускающими его на нескольких потоках, это очень поможет.

В любом случае не используйте стандартную реализацию netlib blas, потому что она слишком медленна для любой серьезной вычислительной работы.

В нашем кластере я также установил AMD ACML, а производительность была похожа на MKL и GotoBlas2. У меня нет никаких жестких цифр.

Я лично рекомендовал бы использовать GotoBlas2, потому что он проще установить и бесплатно.

Если вы хотите ввести код на С++/C, также проверьте Eigen3, который должен превосходить MKL/GotoBlas2 в некоторых случаях и также довольно проста в использовании.

Ответ 3

Возможно, потому что Матрица x Матрица умножается на ограничение памяти, что добавление дополнительных ядер в одну и ту же иерархию памяти не дает вам многого. Конечно, если вы увидите значительное ускорение при переключении на свою реализацию Fortran, я могу быть некорректным.

Я понимаю, что правильное кэширование гораздо важнее для подобных проблем, чем для вычисления мощности. Предположительно BLAS делает это за вас.

Для простого теста вы можете попробовать установить Enthought's для распределения python. Они ссылаются на Intel Math Kernel Library, которые, как я полагаю, используют несколько ядер, если они доступны.

Ответ 4

Вы слышали о MAGMA? Матричная алгебра на GPU и многоядерной архитектуре http://icl.cs.utk.edu/magma/

Проект MAGMA направлен на разработку библиотеки с плотной линейной алгеброй, подобной LAPACK, но для гетерогенных/гибридных архитектур, начиная с современных систем Multicore + GPU.