Numpy SVD在Mac OSX上似乎可以并行化,但在我的Ubuntu虚拟机上却不行

2 投票
1 回答
1329 浏览
提问于 2025-04-18 17:33

我想运行以下脚本:

#python imports
import time

#3rd party imports
import numpy as np
import pandas as pd

def pd_svd(pd_dataframe):
    np_dataframe = pd_dataframe.values
    return np.linalg.svd(pd_dataframe)

if __name__ == '__main__':
    li_times = []
    for i in range(1, 3):
        start = time.time()
        pd_dataframe = pd.DataFrame(np.random.random((3000, 252 * i)))
        pd_svd(pd_dataframe)
        li_times.append(str(time.time() - start))
    print li_times

我在2011年的Macbook Air上,操作系统是OSX 10.9.4,同时也在一个16核的云虚拟机上运行Ubuntu 12.0.4。奇怪的是,在我的Macbook Air上大约需要4秒,而在虚拟机上却要15秒。我用top命令查看了进程,发现我的Ubuntu虚拟机没有使用并行处理,而我的Macbook Air却在使用。

下面是我在Macbook Air上运行top的结果:

在这里输入图片描述

而这是我在Ubuntu虚拟机上的结果:

在这里输入图片描述

有没有人知道为什么我的Macbook Air在进行SVD时速度这么快?特别是,当进行numpy比较时,云虚拟机的速度要快得多,似乎也在使用并行处理(虽然没有用top查看,但速度确实快了好几倍)。

编辑:

这是在云虚拟机上运行np.show_config()的输出:

blas_info:
    libraries = ['blas']
    library_dirs = ['/usr/lib']
    language = f77
lapack_info:
    libraries = ['lapack']
    library_dirs = ['/usr/lib']
    language = f77
atlas_threads_info:
  NOT AVAILABLE
blas_opt_info:
    libraries = ['blas']
    library_dirs = ['/usr/lib']
    language = f77
    define_macros = [('NO_ATLAS_INFO', 1)]
atlas_blas_threads_info:
  NOT AVAILABLE
lapack_opt_info:
    libraries = ['lapack', 'blas']
    library_dirs = ['/usr/lib']
    language = f77
    define_macros = [('NO_ATLAS_INFO', 1)]
atlas_info:
  NOT AVAILABLE
lapack_mkl_info:
  NOT AVAILABLE
blas_mkl_info:
  NOT AVAILABLE
atlas_blas_info:
  NOT AVAILABLE
mkl_info:
  NOT AVAILABLE

1 个回答

4

我怀疑你在云虚拟机上使用的numpy版本只链接到了参考的CBLAS库(*/usr/lib/libblas/libblas.so.3.0)。这个库是单线程的,速度比其他优化过的BLAS实现,比如OpenBLAS和ATLAS,要慢很多。

你可以用ldd命令来确认这一点,检查numpy在运行时链接了哪些库:

~$ ldd /usr/lib/python2.7/dist-packages/numpy/core/_dotblas.so

你可能会看到类似这样的内容:

...
libblas.so.3 => /usr/lib/libblas.so.3 (0x00007f98445e3000)
...

/usr/lib/libblas.so.3是一个符号链接。如果你用readlink跟踪这个链接,你可能会看到这样的结果:

~$ readlink -f /usr/lib/libblas.so.3
/usr/lib/libblas/libblas.so.3.0

这就是那个慢的、单线程的CBLAS库。如果你有管理员权限,最简单的解决办法可能是通过apt-get安装OpenBLAS:

~$ sudo apt-get install libopenblas-base libopenblas-dev

当我在我的服务器上安装这个包时,它把/usr/lib/libblas.so.3的符号链接更新为指向OpenBLAS库,而不是CBLAS:

~$ readlink -f /usr/lib/libblas.so.3
/usr/lib/openblas-base/libblas.so.3

希望这样就能让你使用更快的BLAS库了。

如果因为某种原因你不能通过apt-get解决这个问题,我之前写过一些从源代码构建numpy和OpenBLAS的说明,你可以在这里找到。我也写过一些手动链接到不同BLAS库的说明,使用update-alternatives可以在这里查看


*我在回答中提到的路径是默认的,适用于运行Ubuntu 14.10的服务器,我是通过apt-get安装的numpy。根据你的Ubuntu版本和安装numpy的方式,这些路径可能会有些不同。

撰写回答