LINUX.ORG.RU
ФорумTalks

Откуда такая разница в производительности Matlab и numpy/python2 (в пользу первого)?

 , ,


2

4
>>> setup = """
... 
... import numpy as np
... 
... N = 768
... P = 1024
... 
... A = np.random.random((P, N))
... """
>>> timeit.repeat('A.T.dot(A)', setup=setup, number=10, repeat=3)
[18.736198902130127, 18.66787099838257, 17.36500310897827]

Примерно 1.8 секунд на итерацию, аналог в матлабе:

N = 768;
P = 1024;

A = rand(P, N);

tic
A' * A;
toc

Elapsed time is 0.038807 seconds.

Инверсия матрицы:

>>> setup = """
... import numpy as np
... 
... N = 768
... P = 1024
...  
... A = np.random.random((P, N))
... H =  A.T.dot(A)
... """
>>> timeit.repeat('np.linalg.inv(H)', setup=setup, number=10, repeat=3)
[7.336957216262817, 7.3821821212768555, 7.418352127075195]

примерно 0.7 сеукнд на итераию, в матлабе:

N = 768;
P = 1024;

A = rand(P, N);
H = A' * A;
tic
inv(H);
toc

Elapsed time is 0.083018 seconds.

Итого: matlab обгоняет numpy на 1-2 порядка?! Наверное, я что-то делаю не так... что?

★★★

Последнее исправление: omegatype (всего исправлений: 1)

numpy

py

Вот отсюда. Ты когда-то видел что-то на питоне не тормозящее? Ну кроме скриптов на пару сот строк.
Не видел. Так почему ты считаешь, что этот самый numpy будет такой программой?

Stahl ★★☆
()

Так пистон же! Нечему удивляться.

Meyer ★★★★★
()

Наверное, я что-то делаю не так... что?

Используешь numpy.
Серьёзно, за все 30 лет (или больше?) матлаб вылизан настолько, что блестит в закрытой комнате, стенки которой покрыты вантаблэком.

olibjerd ★★★★★
()
Ответ на: комментарий от olibjerd

Ну я думал, у numpy под капотом C/Fortran/Lapack и на большинстве матричных операций оверхед от самого python будет незначительным, т.к. мы однократно сказали, что мы хотим, а дальше под капотом работает C/LAPAC...

omegatype ★★★
() автор топика

Matlab точно параллелит задачу. 8 ядер моего проца сейчас загружены на максимум повторением этого скрипта. Касательно питона не знаю.

Ещё попробуй

A = gpuArray.rand(P,N);

Sadler ★★★
()
Последнее исправление: Sadler (всего исправлений: 1)

Интересно, все говорят, что виноват питон, а может в матлабе дело? Его уже сколько времени пилят? Наверняка там все сложные вычисления на асме... или еще как оптимизированы.

fjfalcon ★★★
()

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

Sahas ★★★★☆
()
Ответ на: комментарий от Sahas

Что такое «сессия питона»? У меня запущен один интерператор python2, в нем я использую ровно тот код, что привёл выше.

omegatype ★★★
() автор топика
Ответ на: комментарий от Sadler

Сейчас специально програл скрипт на однопроцессорной виртуалке, порядок результата такой же.

omegatype ★★★
() автор топика

J:

   A =: ? 1024 768 $ 0
   6!:2 'A +/ . * (|: A)'
0.765671 

Сделай матрицу побольше

buddhist ★★★★★
()
Последнее исправление: buddhist (всего исправлений: 1)
Ответ на: комментарий от omegatype

Это директива из IPython.

A.T.dot(A) выполняется за 73 мс.

anatoly
()
Ответ на: комментарий от omegatype

там написано

It’s tempting to calculate mean and standard deviation from the result vector and report these. However, this is not very useful. In a typical case, the lowest value gives a lower bound for how fast your machine can run the given code snippet; higher values in the result vector are typically not caused by variability in Python’s speed, but by other processes interfering with your timing accuracy. So the min() of the result is probably the only number you should be interested in.

может, маловато статистики?

Sahas ★★★★☆
()
Последнее исправление: Sahas (всего исправлений: 1)
Ответ на: комментарий от Sahas

И? Вот repeat вернул ряд измерений, у всех одинаковый порядок. Зачем ты приводишь код, о том, как выбирать одно значение из результатов repeat? Ну берите min как советует мануал, порядок-то не поменяется.

omegatype ★★★
() автор топика
Ответ на: комментарий от anatoly

Как это? У меня import в setup-у repeat-а, а setup выполняется тольк один раз.

Вот пример, где setup идет 10 секунд, результирующие тайминги примерно такие же.

>>> setup = """
... import numpy as np
... import time
... 
... N = 768
... P = 1024
... 
... time.sleep(10)
... 
... A = np.random.random((P, N))
... """
>>> 
>>> 
>>> timeit.repeat('A.T.dot(A)', setup=setup, number=10, repeat=3)
[20.86553192138672, 21.162163019180298, 21.352187871932983]
omegatype ★★★
() автор топика
Последнее исправление: omegatype (всего исправлений: 1)
Ответ на: комментарий от omegatype

да, стормозил. Как ни считай, всё равно медленно получается...

Sahas ★★★★☆
()
Ответ на: комментарий от omegatype

У вас там в питоне нет профилировщика какого, чтоль? Я вот в матлабе вижу, на что у меня уходят ресурсы.

Sadler ★★★
()
Ответ на: комментарий от Sadler

Есть.... но, у меня тут всего одна строчка кода, что профилировать? Сам numpy? Мне такая задача не представляется возможнной.

omegatype ★★★
() автор топика

matlab обгоняет numpy на 1-2 порядка?!

Разница в 2 порядка наводит на подозрение, что Matlab просто не выполняет операцию, пока ее результат не понадобился.

tailgunner ★★★★★
()
Ответ на: комментарий от anatoly

Может, дело в версии python, я поправил ОП, речь о python2. У меня на ipython опять те же 2 секунды:

In [1]: import numpy as np
In [2]: N = 768
In [3]: P = 1024
In [4]: A = np.random.random((P, N))
In [5]: %%timeit
   ...: A.T.dot(A)
   ...: 
1 loops, best of 3: 1.83 s per loop

Вы у себя точно такой же код гоняете и получаете 72 мс?

omegatype ★★★
() автор топика
Ответ на: комментарий от Stahl

Не видел. Так почему ты считаешь, что этот самый numpy будет такой программой?

Потому, что в кишках у numpy вовсе не код на пистоне. Иногда лучше жевать.

ptarh ★★★★★
()
Ответ на: комментарий от tailgunner

Разница в 2 порядка наводит на подозрение, что Matlab просто не выполняет операцию, пока ее результат не понадобился

Нет. Следующий код даёт приблизительно такое же время (с разницей на время mean2):

tic
    A = A' * A;
toc

mean2(A)
Sadler ★★★
()
Ответ на: комментарий от tailgunner

Гм.. вот такой код:

N = 768;
P = 1024;

A = rand(P, N);

tic
H = A' * A;
size(H)
sum(sum(H))
toc

Имеет тот же порядок, попытки менять rand на randn (что бы убедится в новых значениях) приводят (иногда, но не всегда) к возрастанию времни на конкретно моём окружении с 0.08 до 0.10 - 0.12, но все-равно примерно тоже.

omegatype ★★★
() автор топика
Ответ на: комментарий от Sadler

Следующий код даёт приблизительно такое же время (с разницей на время mean2)

Если tic tac - это скобки для измерения времени, то результат и должен быть одинаковым.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

А, точно, вру, даже без mean2. То есть всё-таки питон чего-то больно тормозной у человека. А я ещё на матлаб обижаюсь за тормоза в расчётах.

Sadler ★★★
()
Последнее исправление: Sadler (всего исправлений: 1)
Ответ на: комментарий от dinn

Пример:
Стандартный BLAS

octave:1> test_1
Elapsed time is 0.310091 seconds.
octave:2> test_1
Elapsed time is 0.400823 seconds.
octave:3> test_1
Elapsed time is 0.309284 seconds.
OpenBLAS
octave:1> test_1
Elapsed time is 0.052923 seconds.
octave:2> test_1
Elapsed time is 0.0540769 seconds.
octave:3> test_1
Elapsed time is 0.050236 seconds.

dinn ★★★★★
()
Ответ на: комментарий от tailgunner

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

omegatype ★★★
() автор топика
Последнее исправление: omegatype (всего исправлений: 1)
Ответ на: комментарий от dinn

По ходу просто BLAS:

lapack_info:
    libraries = ['lapack']
    library_dirs = ['/usr/lib64']
    language = f77
lapack_opt_info:
    libraries = ['lapack', 'blas']
    library_dirs = ['/usr/lib64']
    language = f77
    define_macros = [('NO_ATLAS_INFO', 1)]
openblas_lapack_info:
  NOT AVAILABLE
blas_info:
    libraries = ['blas']
    library_dirs = ['/usr/lib64']
    language = f77
atlas_3_10_blas_threads_info:
  NOT AVAILABLE
atlas_threads_info:
  NOT AVAILABLE
atlas_3_10_threads_info:
  NOT AVAILABLE
atlas_blas_info:
  NOT AVAILABLE
atlas_3_10_blas_info:
  NOT AVAILABLE
atlas_blas_threads_info:
  NOT AVAILABLE
openblas_info:
  NOT AVAILABLE
blas_mkl_info:
  NOT AVAILABLE
blas_opt_info:
    libraries = ['blas']
    library_dirs = ['/usr/lib64']
    language = f77
    define_macros = [('NO_ATLAS_INFO', 1)]
atlas_info:
  NOT AVAILABLE
atlas_3_10_info:
  NOT AVAILABLE
lapack_mkl_info:
  NOT AVAILABLE
mkl_info:
  NOT AVAILABLE

Сейчас пойду гуглить, но если openblas такой классный, что же он не в коробке вместо просто blas-а... ?

omegatype ★★★
() автор топика
Ответ на: комментарий от tailgunner

Еще раз - тест без mean2 бессмысленен, если Matlab вычисляет лениво

Но тест с mean2, просто mean2 вне tic toc. Вариант с «компилятор это посчитает в момент вызова mean2» я даже не рассматриваю, т.к. это не соответствует наблюдаемым через профилировщик результатам.

Sadler ★★★
()
Ответ на: комментарий от tailgunner

Но это за счет распараллеливания?

Не только, там оптимизации под конкретные процессоры. Как минимум это даёт один порядок. Всё-таки осталось найти только один, а не два. Возможны оптимизации в других библиотеках, или что-то, заточенное в Matlab. Например одна из причин проигрыша Octave по отношению к Matlab - работа с памятью.

dinn ★★★★★
()
Ответ на: комментарий от omegatype

Сейчас пойду гуглить, но если openblas такой классный, что же он не в коробке вместо просто blas-а... ?

По крайней мере на Debian он в репозитории - если поставить, автоматически используется.

tailgunner ★★★★★
()
Ответ на: комментарий от omegatype

Потому что стандартная реализация в отличие от openblas и atlas работает всегда и как надо. А у них встречаются регрессии. В любом случае основные дистрибутивы поддерживают смену системных реализаций blas и lapack.

dinn ★★★★★
()
Ответ на: комментарий от tailgunner

если поставить, автоматически используется.

Нет, на Debian и openSUSE можно менять используемую реализацию через update-alternatives. Про другие дистрибутивы не знаю как там именно сделано.

dinn ★★★★★
()

Еще вопрос - откуда numpy? Из стандартных бубунтяшных реп? Если да, то поставь EPD и протестируй на нем.

ptarh ★★★★★
()
Ответ на: комментарий от dinn

если поставить, автоматически используется.

Нет,

Да. Я попробовал.

на Debian и openSUSE можно менять используемую реализацию через update-alternatives

Да. Но это же может сделать и postinst-скрипт.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Но это же может сделать и postinst-скрипт.

Это скорее дело вкусов и мнений сопровождающего пакет. Я предпочитаю давать пользователю полное ручное управление в данном вопросе.

dinn ★★★★★
()
Ответ на: комментарий от dinn

это же может сделать и postinst-скрипт.

Это скорее дело вкусов и мнений сопровождающего пакет.

Или policy. Но я говорил о том, как оно сделано сейчас в Debian Stable.

tailgunner ★★★★★
()
Ответ на: комментарий от omegatype

Ну это и разгадка скорее всего. Смотри, тут с графиками: https://store.continuum.io/cshop/accelerate/

Проблема в том, что за оптимизированный numpy они хотят денег. Но, если ты academic user, то EPD и анаконда дадут тебе лицензию задаром.

ptarh ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.