具有不同BLAS实现的NumPy的性能

时间:2014-10-22 15:38:02

标签: numpy amazon-ec2 blas accelerate-framework openblas

我正在运行一个用Python实现并使用NumPy的算法。算法中计算成本最高的部分涉及解决一组线性系统(即调用numpy.linalg.solve()。我想出了这个小基准:

import numpy as np
import time

# Create two large random matrices
a = np.random.randn(5000, 5000)
b = np.random.randn(5000, 5000)

t1 = time.time()
# That's the expensive call:
np.linalg.solve(a, b)
print time.time() - t1

我一直在运行:

  1. 我的笔记本电脑,2013年末的MacBook Pro 15" 4核2GHz(sysctl -n machdep.cpu.brand_string给我 Intel(R)Core(TM)i7-4750HQ CPU @ 2.00GHz
  2. Amazon EC2 c3.xlarge实例,包含4个vCPU。亚马逊将它们宣传为"高频英特尔至强E5-2680 v2(Ivy Bridge)处理器"
  3. 底线:

    • 在Mac上,它以 ~4.5秒
    • 运行
    • 在EC2实例上,它以 ~19.5秒
    • 运行

    我也尝试过其他基于OpenBLAS / Intel MKL的设置,运行时总是与我在EC2实例上得到的结果相同(模块化硬件配置。)

    任何人都可以解释为什么Mac上的性能(使用Accelerate Framework)是> 4x更好?下面提供了有关NumPy / BLAS设置的更多详细信息。

    笔记本电脑设置

    numpy.show_config()给了我:

    atlas_threads_info:
      NOT AVAILABLE
    blas_opt_info:
        extra_link_args = ['-Wl,-framework', '-Wl,Accelerate']
        extra_compile_args = ['-msse3', '-I/System/Library/Frameworks/vecLib.framework/Headers']
        define_macros = [('NO_ATLAS_INFO', 3)]
    atlas_blas_threads_info:
      NOT AVAILABLE
    openblas_info:
      NOT AVAILABLE
    lapack_opt_info:
        extra_link_args = ['-Wl,-framework', '-Wl,Accelerate']
        extra_compile_args = ['-msse3']
        define_macros = [('NO_ATLAS_INFO', 3)]
    atlas_info:
      NOT AVAILABLE
    lapack_mkl_info:
      NOT AVAILABLE
    blas_mkl_info:
      NOT AVAILABLE
    atlas_blas_info:
      NOT AVAILABLE
    mkl_info:
      NOT AVAILABLE
    

    EC2实例设置:

    在Ubuntu 14.04上,我用

    安装了OpenBLAS
    sudo apt-get install libopenblas-base libopenblas-dev
    

    安装NumPy时,我创建了一个site.cfg,其中包含以下内容:

    [default]
    library_dirs= /usr/lib/openblas-base
    
    [atlas]
    atlas_libs = openblas
    

    numpy.show_config()给了我:

    atlas_threads_info:
        libraries = ['lapack', 'openblas']
        library_dirs = ['/usr/lib']
        define_macros = [('ATLAS_INFO', '"\\"None\\""')]
        language = f77
        include_dirs = ['/usr/include/atlas']
    blas_opt_info:
        libraries = ['openblas']
        library_dirs = ['/usr/lib']
        language = f77
    openblas_info:
        libraries = ['openblas']
        library_dirs = ['/usr/lib']
        language = f77
    lapack_opt_info:
        libraries = ['lapack', 'openblas']
        library_dirs = ['/usr/lib']
        define_macros = [('ATLAS_INFO', '"\\"None\\""')]
        language = f77
        include_dirs = ['/usr/include/atlas']
    openblas_lapack_info:
      NOT AVAILABLE
    lapack_mkl_info:
      NOT AVAILABLE
    blas_mkl_info:
      NOT AVAILABLE
    mkl_info:
      NOT AVAILABLE
    

1 个答案:

答案 0 :(得分:3)

这种行为的原因可能是Accelerate使用多线程,而其他人则不会。

大多数BLAS实现遵循环境变量OMP_NUM_THREADS来确定要使用的线程数。我相信如果没有明确说明,他们只使用1个线程。 Accelerate's man page但是,默认情况下会启用线程功能;可以通过设置环境变量VECLIB_MAXIMUM_THREADS来关闭它。

要确定这是否真的发生了什么,请尝试

export VECLIB_MAXIMUM_THREADS=1

在调用Accelerate版本之前,

export OMP_NUM_THREADS=4

其他版本。

无论这是否真的是这个原因,当你使用BLAS来确保控制正在发生的事情时,总是设置这些变量是一个好主意。