是ubuntu';BLAS的实现是并行的吗?

是ubuntu';BLAS的实现是并行的吗?,ubuntu,numpy,blas,atlas,ubuntu-15.10,Ubuntu,Numpy,Blas,Atlas,Ubuntu 15.10,Linux提供了伟大的并行化工具,如pthreads和openmp。它们使并行计算相对容易。尽管我不是汇编级优化方面的专家,但在大型阵列上并行实现元素操作似乎相当简单。矩阵乘法、求解线性系统等的Idem 但是,如果我从apt-get(sudo-apt-get-install-python3-python3-dev-python3-numpy-ipython3)安装numpy,那么元素操作只在一个内核上执行。这是不幸的,因为python由于GIL而不提供并行化。在BLAS的较低级别上进行并行化将允

Linux提供了伟大的并行化工具,如pthreads和openmp。它们使并行计算相对容易。尽管我不是汇编级优化方面的专家,但在大型阵列上并行实现元素操作似乎相当简单。矩阵乘法、求解线性系统等的Idem

但是,如果我从
apt-get
sudo-apt-get-install-python3-python3-dev-python3-numpy-ipython3
)安装numpy,那么元素操作只在一个内核上执行。这是不幸的,因为python由于GIL而不提供并行化。在BLAS的较低级别上进行并行化将允许我利用所有内核,并获得显著的加速(对于我的i7,有8个线程,速度为6-8),从而减少等待和更多实验,同时仍然使用舒适的语言(python)

这个

简单的元素wise
x**x
可以并行运行,但对于我的默认ubuntu apt get numpy安装,它只在一个内核上运行

西亚诺也是如此。我认为theano也在引擎盖下使用BLAS,因为它的一个依赖项是numpy(numpy反过来使用BLAS)。每当我训练keras或theano神经网络时,只使用一个核心

据我所知,BLAS只是一个接口描述,而不是实际的实现。然而,在ubuntu中有一个
libblas3
libatlas3 base
包,它们似乎是不同的

此外:从源代码处编译atlas并不是一个很大的成功:配置脚本不断抱怨节流,这似乎是我的CPU固有的,它总是以低于最大频率100MHz的频率运行,它也有一个2.4GHz的最大值,并且有可能在半分钟左右的时间内提升到3.4GHz,我认为这就是所谓的热节流

对于矩阵等的numpy操作的多核使用,我有哪些选择?它们是从盒子里出来的吗?若否,原因为何?为什么很难为numpy提供并行的线性代数引擎?对于4个或8个cpu线程,我认为汇编级别的单线程优化无法战胜这一点

编辑

我还尝试了以下命令:

OMP_NUM_THREADS=8 LD_PRELOAD=/usr/lib/atlas-base/libatlas.so python3 -c 'import numpy; x=numpy.arange(1e8); y=x**x'
OMP_NUM_THREADS=8 LD_PRELOAD=/usr/lib/libopenblas.so python3 -c 'import numpy; x=numpy.arange(1e8); y=x**x'

它也只使用1个内核。

Elementwise操作()由Numpy C代码实现,没有并行化。只有一些线性代数运算被委托给BLAS库,并且可以并行运行,具体取决于所使用的库。再次使用
numpy.dot
和大型2D数组检查线程是否启用。为什么元素操作不能并行化?这似乎是一个易于实现的好方法,尤其是因为python的并行化非常痛苦。我认为最重要的原因是Numpy每次都必须在整个数组上循环,对于每个操作。这使得Numpy代码很快就受到内存带宽的限制,而不是太多的CPU功耗限制。因此,多线程的潜在收益是有限的。但也许你也低估了实施的难度。当然,对于1D阵列,它看起来确实可行。但问题是,即使是1D操作也会通过通用的ufunc机制,该机制设计用于处理数量可变的多维参数,还负责缓冲和广播。请注意,在某些情况下(例如,大量使用三角函数),使用Python进行手动线程处理可能会带来回报,因为Numpy ufuncs通常在内部数组迭代器启动之前释放GIL。对于其他情况,还有
numexpr
模块。@morningsun我明白了,而且在数组的子集上发生了很多操作,因此还需要注意步长、偏移量等。不过,低级别的并行化是天赐良机,因为它减轻了对高级多处理并行化的需求,而这种并行化通常很难提高内存效率。然而,丑陋的事实是,在许多numpy实验之后,我从未见过我的八个线程(4个内核)中有一个以上被使用。在我转到numpy之前,我在Matlab中运行了许多实验,我可以使用
parfor
轻松地并行化(我承认,在更高的级别上)。Elementwise操作()由numpy C代码实现,而不是并行化。只有一些线性代数运算被委托给BLAS库,并且可以并行运行,具体取决于所使用的库。再次使用
numpy.dot
和大型2D数组检查线程是否启用。为什么元素操作不能并行化?这似乎是一个易于实现的好方法,尤其是因为python的并行化非常痛苦。我认为最重要的原因是Numpy每次都必须在整个数组上循环,对于每个操作。这使得Numpy代码很快就受到内存带宽的限制,而不是太多的CPU功耗限制。因此,多线程的潜在收益是有限的。但也许你也低估了实施的难度。当然,对于1D阵列,它看起来确实可行。但问题是,即使是1D操作也会通过通用的ufunc机制,该机制设计用于处理数量可变的多维参数,还负责缓冲和广播。请注意,在某些情况下(例如,大量使用三角函数),使用Python进行手动线程处理可能会带来回报,因为Numpy ufuncs通常在内部数组迭代器启动之前释放GIL。对于其他情况,还有
numexpr
模块。@morningsun我明白了,而且在数组的子集上发生了很多操作,因此还需要注意步长、偏移量等。不过,低级别的并行化是天赐良机,因为它减轻了对高级多处理并行化的需求,而这种并行化通常很难提高内存效率。丑陋的事实
OMP_NUM_THREADS=8 LD_PRELOAD=/usr/lib/atlas-base/libatlas.so python3 -c 'import numpy; x=numpy.arange(1e8); y=x**x'
OMP_NUM_THREADS=8 LD_PRELOAD=/usr/lib/libopenblas.so python3 -c 'import numpy; x=numpy.arange(1e8); y=x**x'