Fragen:Optimierung der numpy Array-Multiplikation: * schneller als numpy.dot?
1) Wie es ist, dass numpy.dot()
langsamer als *
im Beispielcode unten, wenn BLAS verwendet wird?
2) Gibt es eine Möglichkeit, numpy.dot()
anstelle von *
in diesem Fall für schnellere Array-Multiplikation implementiert werden? Ich denke, dass mir eine entscheidende Information fehlt, die Frage 1 beantworten und meinen würde, dass numpy.dot()
mindestens genauso schnell ist wie *
, wenn nicht schneller.
Details sind unten enthalten. Vielen Dank im Voraus für Antworten und Hilfe.
Details:
ich ein Programm schreibe, die 2.7 (64-Bit), numpy 1.11.2, Anaconda2 auf Windows 7. Zur Verbesserung der Genauigkeit der ich brauche Programmausgabe mit Python gekoppelter PDEs löst um große Arrays zu verwenden (Shape (2, 2^14) und größer) und kleine Integrationsschritte, was zu einer gigantischen Anzahl von Array-Multiplikationsoperationen pro Simulation führt, die ich für die Geschwindigkeit optimieren muss.
Mit looked around scheint es, als ob numpy.dot()
für schnellere Array-Multiplikation in Bezug auf *
verwendet werden sollte, solange BLAS installiert ist und mit numpy arbeitet. Dies wird häufig empfohlen. Allerdings, wenn ich unter den Timer-Skript verwenden, ist *
schneller als numpy.dot()
um mindestens einen Faktor 7 In einigen Fällen kann diese Faktoren erhöht> 1000:
from __future__ import division
import numpy as np
import timeit
def dotter(a, b):
return np.dot(a, b)
def timeser(a, b):
return a*b
def wrapper(func, a, b):
def wrapped():
return func(a, b)
return wrapped
size = 100
num = int(3e5)
a = np.random.random_sample((size, size))
b = np.random.random_sample((size, size))
wrapped = wrapper(dotter, a, b)
dotTime = timeit.timeit(wrapped, number=num)/num
print "\nTime for np.dot: ", dotTime
wrapped = wrapper(timeser, a, b)
starTime = timeit.timeit(wrapped, number=num)/num
print "\nTime for *: ", starTime
print "dotTime/starTime: ", dotTime/starTime
Diese Ausgänge:
Time for np.dot: 8.58201189949e-05
Time for *: 1.07564737429e-05
dotTime/starTime: 7.97846218436
sowohl numpy.dot()
und *
werden über mehrere Kerne verteilt, was ich denke, legt nahe, dass BLAS zu einem gewissen Grad funktioniert, zumindest:
bei numpy.__config__.show()
Blick es scheint, als ob ich BLAS und lapack bin mit (wenn auch nicht openblas_lapack?):
lapack_opt_info:
libraries = ['mkl_lapack95_lp64', 'mkl_blas95_lp64', 'mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'libiomp5md', 'libifportmd']
library_dirs = ['C:/Program Files (x86)/Intel/Composer XE/mkl/lib/intel64']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['C:/Program Files (x86)/Intel/Composer XE/mkl/include']
blas_opt_info:
libraries = ['mkl_lapack95_lp64', 'mkl_blas95_lp64', 'mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'libiomp5md', 'libifportmd']
library_dirs = ['C:/Program Files (x86)/Intel/Composer XE/mkl/lib/intel64']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['C:/Program Files (x86)/Intel/Composer XE/mkl/include']
openblas_lapack_info:
NOT AVAILABLE
lapack_mkl_info:
libraries = ['mkl_lapack95_lp64', 'mkl_blas95_lp64', 'mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'libiomp5md', 'libifportmd']
library_dirs = ['C:/Program Files (x86)/Intel/Composer XE/mkl/lib/intel64']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['C:/Program Files (x86)/Intel/Composer XE/mkl/include']
blas_mkl_info:
libraries = ['mkl_lapack95_lp64', 'mkl_blas95_lp64', 'mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'libiomp5md', 'libifportmd']
library_dirs = ['C:/Program Files (x86)/Intel/Composer XE/mkl/lib/intel64']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['C:/Program Files (x86)/Intel/Composer XE/mkl/include']
Der alte Vergleich zwischen Apfel und Orangen ... – Bakuriu
@Bakuriu Ich kann nicht helfen. Alte Gewohnheiten sterben offenbar hart. –