优化numpy数组乘法:*比numpy.dot更快?

时间:2017-01-05 14:10:36

标签: python arrays performance numpy blas

问题:

1)当使用BLAS时,numpy.dot()在下面的示例代码中如何慢于*

2)在这种情况下,是否有一种方法可以实现numpy.dot()而不是*更快的数组乘法?我认为我错过了一条能回答问题1的重要信息,并表示numpy.dot()至少与*一样快,如果不是更快的话。

详情如下。提前感谢您的回答和帮助。

详细信息:

我正在编写一个程序,它在Windows 7上使用python 2.7(64位),numpy 1.11.2,Anaconda2解决耦合的PDE。为了提高程序输出的准确性,我需要使用大型数组(形状(2, 2 ^ 14)和更大的集成步骤,每个模拟产生了大量的数组乘法运算,我需要优化速度。

拥有looked around,只要安装BLAS并使用numpy,似乎numpy.dot()应该用于*的更快的数组乘法。这经常被推荐。但是,当我使用下面的计时器脚本时,*numpy.dot()快至少7倍。在某些情况下,这会增加到因子> 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

输出:

Time for np.dot:  8.58201189949e-05
Time for *:  1.07564737429e-05
dotTime / starTime:  7.97846218436

numpy.dot()*都分布在多个核心上,我认为这表明BLAS在某种程度上起作用,至少:

enter image description here

numpy.__config__.show()好像我正在使用BLAS和lapack(虽然不是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']

1 个答案:

答案 0 :(得分:4)

np.dot调用矩阵 - 矩阵乘法,而*是元素乘法。对于Python 3.5 +,矩阵 - 矩阵乘法的符号为@