我正在使用一些相当大的,密集的numpy浮点数组,这些数组目前驻留在PyTables CArray
的磁盘上.我需要能够执行使用这些阵列效率点的产物,例如C = A.dot(B)
,其中A
是一个巨大的(〜1E4 X 3E5 FLOAT32)存储器映射阵列,以及B
和C
较小numpy的数组,其驻留在核心存储器.
我现在正在做的是使用数据将数据复制到内存映射的numpy数组中np.memmap
,然后np.dot
直接调用内存映射数组.这是有效的,但我怀疑标准np.dot
(或者它调用的底层BLAS函数)在计算结果所需的I/O操作数量方面可能不是很有效.
我在这篇评论文章中遇到了一个有趣的例子.使用3x嵌套循环计算的天真点积,如下所示:
def naive_dot(A, B, C):
for ii in xrange(n):
for jj in xrange(n):
C[ii,jj] = 0
for kk in xrange(n):
C[ii,jj] += A[ii,kk]*B[kk,jj]
return C
Run Code Online (Sandbox Code Playgroud)
需要O(n ^ 3)个 I/O操作来计算.
但是,通过在适当大小的块中处理数组:
def block_dot(A, B, C, M):
b = sqrt(M / 3)
for ii in xrange(0, n, b):
for jj in xrange(0, n, b):
C[ii:ii+b,jj:jj+b] = …
Run Code Online (Sandbox Code Playgroud) 这里使用hdf5的矩阵乘法我使用hdf5(pytables)进行大矩阵乘法,但我很惊讶因为使用hdf5它的工作速度更快,然后在RAM中使用普通的numpy.dot和存储矩阵,这种行为的原因是什么?
也许在python中有一些更快的矩阵乘法函数,因为我仍然使用numpy.dot进行小块矩阵乘法.
这是一些代码:
假设矩阵可以适合RAM:在矩阵10*1000 x 1000上进行测试.
使用默认numpy(我认为没有BLAS lib).普通的numpy数组在RAM中:时间9.48
如果A,B在RAM中,C在磁盘上:时间1.48
如果磁盘上的A,B,C:时间372.25
如果我使用numpy与MKL结果是:0.15,0.45,43.5.
结果看起来很合理,但我仍然不明白为什么在第一种情况下块乘法更快(当我们将A,B存储在RAM中时).
n_row=1000
n_col=1000
n_batch=10
def test_plain_numpy():
A=np.random.rand(n_row,n_col)# float by default?
B=np.random.rand(n_col,n_row)
t0= time.time()
res= np.dot(A,B)
print (time.time()-t0)
#A,B in RAM, C on disk
def test_hdf5_ram():
rows = n_row
cols = n_col
batches = n_batch
#using numpy array
A=np.random.rand(n_row,n_col)
B=np.random.rand(n_col,n_row)
#settings for all hdf5 files
atom = tables.Float32Atom() #if store uint8 less memory?
filters = tables.Filters(complevel=9, complib='blosc') # tune parameters
Nchunk = 128 # ?
chunkshape = (Nchunk, …
Run Code Online (Sandbox Code Playgroud)