我有一个numpy
脚本,它在以下代码中占用了大约50%的运行时间:
s = numpy.dot(v1, v1)
,其中
v1 = v[1:]
和v
是存储在连续内存中的4000个元素1D ndarray
float64
(v.strides
是(8,)
)。
有关加快这项工作的建议吗?
编辑这是在英特尔硬件上。以下是我numpy.show_config()
的输出:
atlas_threads_info:
libraries = ['lapack', 'ptf77blas', 'ptcblas', 'atlas']
library_dirs = ['/usr/local/atlas-3.9.16/lib']
language = f77
include_dirs = ['/usr/local/atlas-3.9.16/include']
blas_opt_info:
libraries = ['ptf77blas', 'ptcblas', 'atlas']
library_dirs = ['/usr/local/atlas-3.9.16/lib']
define_macros = [('ATLAS_INFO', '"\\"3.9.16\\""')]
language = c
include_dirs = ['/usr/local/atlas-3.9.16/include']
atlas_blas_threads_info:
libraries = ['ptf77blas', 'ptcblas', 'atlas']
library_dirs = ['/usr/local/atlas-3.9.16/lib']
language = c
include_dirs = ['/usr/local/atlas-3.9.16/include']
lapack_opt_info:
libraries = ['lapack', 'ptf77blas', 'ptcblas', 'atlas']
library_dirs = ['/usr/local/atlas-3.9.16/lib']
define_macros = [('ATLAS_INFO', '"\\"3.9.16\\""')]
language = f77
include_dirs = ['/usr/local/atlas-3.9.16/include']
lapack_mkl_info:
NOT AVAILABLE
blas_mkl_info:
NOT AVAILABLE
mkl_info:
NOT AVAILABLE
答案 0 :(得分:5)
也许罪魁祸首是复制传递给 dot 的数组。
正如Sven所说, dot 产品依赖于BLAS操作。这些操作需要以连续的C顺序存储的数组。如果传递给 dot 的两个数组都在C_CONTIGUOUS中,那么你应该看到更好的性能。
当然,如果传递给dot的两个数组确实是1D(8,)那么你应该看到两者 C_CONTIGUOUS和F_CONTIGUOUS标志设置为True;但如果它们是(1,8),那么你可以看到混合顺序。
>>> w = NP.random.randint(0, 10, 100).reshape(100, 1)
>>> w.flags
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : False
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
另一种方法:使用BLAS中的_GEMM,它通过模块 scipy.linalg.fblas 公开。 (两个数组A和B显然是Fortran顺序,因为使用了 fblas 。)
from scipy.linalg import fblas as FB
X = FB.dgemm(alpha=1., a=A, b=B, trans_b=True)
答案 1 :(得分:5)
你的阵列不是很大,所以ATLAS可能做得不多。您对以下Fortran计划的时间安排是什么?假设ATLAS没有做太多,这应该让你了解如果没有任何python开销,dot()的速度有多快。使用gfortran -O3,我获得了5 +/- 0.5 us的速度。
program test
real*8 :: x(4000), start, finish, s
integer :: i, j
integer,parameter :: jmax = 100000
x(:) = 4.65
s = 0.
call cpu_time(start)
do j=1,jmax
s = s + dot_product(x, x)
enddo
call cpu_time(finish)
print *, (finish-start)/jmax * 1.e6, s
end program test
答案 2 :(得分:4)
我唯一可以想到的是加速这一点是为了确保你的NumPy安装是针对优化的BLAS库(如ATLAS)编译的。 numpy.dot()
是使用BLAS的少数几个NumPy函数之一。
答案 3 :(得分:2)
numpy.dot将使用多线程。确保它与顶部一起。我知道人们没有在numpy w / atlas中进行多线程工作的情况。此外,值得尝试使用针对intel mkl库编译的numpy版本。它们包括应该比英特尔硬件上的地图集更快的blas例程。你可以试试enthought的python发行版。包含所有这些内容,对于拥有edu电子邮件帐户的人来说是免费的。