scipy.weave.inline的性能

2 投票
1 回答
1862 浏览
提问于 2025-04-17 04:49

我是一名刚开始学习Python的新手,想了解这个很棒的编程语言。我尝试使用scipy.weave.inline来加速一些计算。为了学习,我试着用scipy.weave.inline实现矩阵乘法。我没有加入任何错误处理,只是想试试,以便更好地理解它。代码如下:

import scipy.weave
def cmatmul(A,B):
    R = numpy.zeros((A.shape[0],B.shape[1]))
    M = R.shape[0]
    N = R.shape[1]
    K = A.shape[1]

    code = \
    """
    for (int i=0; i<M; i++)
        for (int j=0; j<N; j++)
            for (int k=0; k<K; k++)
                R(i,j) += A(i,k) * B(k,j);
    """
    scipy.weave.inline(code, ['R','A','B','M','N','K'], \
                       type_converters=scipy.weave.converters.blitz, \
                       compiler='gcc')
    return R

当我和numpy.dot进行比较时,发现使用weave.inline的版本大约需要numpy.dot的50倍时间。我知道numpy在可以使用的时候非常快。即使在处理像1000 x 1000这样的大矩阵时,这个差距也很明显。

我检查了numpy.dot和scipy.weave.inline,发现它们在计算时都只使用了一个核心,且使用率达到了100%。numpy.dot的性能是10.0 GFlops,而我笔记本电脑的理论性能是11.6 GFlops(双精度)。在单精度下,我测得的性能是预期的双倍。但scipy.weave.inline的表现远远不如,只有它的1/50。

这个差距是正常的吗?还是我哪里做错了?

1 个回答

7

你实现了一个简单的矩阵乘法算法,这个算法可以通过 scipy.weave 编译成快速的机器代码。

不过,其实还有一些不太明显的、更有效利用CPU缓存的矩阵乘法算法(通常是把矩阵分成小块来处理),这样可以提高速度。而且,如果你针对特定的CPU做一些优化,速度也会更快。默认情况下,Numpy会使用一个优化过的BLAS库来进行这个操作,如果你安装了这个库的话。这些库的速度通常会比你自己写的代码快很多,除非你做了大量的研究。

撰写回答