2015-01-04 2 views
3

У меня есть следующий код Python :Матричное умножение Numpy.dot: (n-by-m) * (m-by-k) и (m-by-k) * (k-by-n) имеют очень разные скорости

import numpy 
import time 

A = numpy.random.random((10,60000)) 
B = numpy.random.random((60000,785)) 
C = numpy.random.random((785,10)) 

t = time.time() 
D = A.dot(B) 
print "%.2f s" % (time.time() - t) 

t = time.time() 
E = B.dot(C) 
print "%.2f s" % (time.time() - t) 

Я думаю, что две матрицы умножений A * B и B * C следует принимать примерно такое же количество времени, потому что оба умножений включают 10 * 60000 * 785 операций умножения.

Однако на разных машинах у меня очень разные тайминги. На моем ноутбуке (Windows 7, 2,40 ГГц процессор, 8 Гб памяти, Python 2.7, Numpy 1.7.1), я получил:

0.21 s 
0.21 s 

что является нормальным. На кластерном компьютере (Linux CentOS 5,6, 2,66 ГГц, 16G памяти, Python 2.7.3, Numpy 1.8.1), я получил:

6.77 s 
1.10 s 

где A * B гораздо медленнее, чем B * С

Может ли кто-нибудь объяснить, почему два умножения занимают разные промежутки времени? Я не уверен, какие конфигурации релевантны, но я постараюсь предоставить любую необходимую информацию.

+0

Является ли 'numpy.transpose (B) .dot (numpy.transpose (A))' намного медленнее, чем 'B * C'? Если нет, я подозреваю, что это проблема с макетом памяти. – user14717

+0

Обратите внимание, что различия между машинами могут быть вызваны различными библиотеками BLAS. Я уверен, что ваш CentOS numpy не связан с «полной» BLAS-библиотекой и использует встроенный (но медленный) BLAS-подзадачный элемент numpy. Посмотрите на вывод 'numpy.show_config()' для обеих систем для сравнения. –

+0

@JoeKington Конфигурации действительно разные. В Windows у меня есть следующее: blas_opt_info (библиотеки: f77blas, cblas, atlas, язык: c), lapack_opt_info (библиотеки: lapack, f77blas, cblas, атлас, язык: f77), atlas_info (библиотеки: lapack, f77blas, cblas, atlas , язык: f77), atlas_blas_info (библиотеки: f77blas, cblas, атлас, язык: c). В Linux у меня есть: blas_info (библиотеки: blas, язык: f77), lapack_info (библиотеки: lapack, язык: f77), blas_opt_info (библиотеки: blas, язык: f77), lapack_opt_info (библиотеки: lapack, blas, язык: f77) , – Maigo

ответ

0

В A больше элементов, поэтому результаты интуитивно понятны.

+0

Я не понимаю, что вы имеете в виду. Временная сложность умножения матрицы n-m-m и матрицы m-by-k равна O (nmk).Кроме того, тот факт, что я получаю разные тайминги на разных машинах, говорит о том, что он может иметь какое-то отношение к конфигурациям. – Maigo

0

(Слишком долго для комментариев, а не ответ)

Если вы запустите следующий, вы получите широкие различия в производительности?

#!/usr/bin/env python3.4                 
import numpy 
import time 

A = numpy.random.random((10,60000)) 
B = numpy.random.random((60000,785)) 
C = numpy.random.random((785,10)) 

t = time.time() 
D = A.dot(B) 
print("%.2f s" % (time.time() - t)) 

t = time.time() 
D = numpy.transpose(B).dot(numpy.transpose(A)) 
print("%.2f s" % (time.time() - t)) 

t = time.time() 
D = B.dot(C) 
print("%.2f s" % (time.time() - t)) 

t = time.time() 
D = numpy.transpose(C).dot(numpy.transpose(B)) 
print("%.2f s" % (time.time() - t)) 

При запуске этого я получить

0.21 s 
0.22 s 
0.44 s 
0.22 s 

Это сильно свидетельствует о различиях шаблонов доступа к памяти.

+0

У меня есть интересные шаблоны: В Windows: 0.20s, 1.15s, 0.20s, 1.16s; В Linux: 6.82s, 6.79s, 1.10s, 1.31s. – Maigo

+0

Я только что установил Python Anaconda в соответствии с комментарием @ JoeKington, и теперь я получаю 0.22s, 0.22s, 0.27s, 0.27s. Это кажется нормальным. Благодаря! – Maigo

Смежные вопросы