我正在编写一个必须计算大量特征值问题的代码(典型的矩阵维度是几百个)。我想知道是否可以通过使用IPython.parallel
module. 作为前 MATLAB 用户和 Python 新手,我一直在寻找类似于 MATLAB 的parfor
...
在网上的一些教程之后,我编写了一个简单的代码来检查它是否可以加快计算速度,我发现它并没有而且实际上通常会减慢它的速度(视情况而定)。我认为,我可能遗漏了一点,并且可能scipy.linalg.eig
以这样一种方式实现,即它使用所有可用的内核并通过尝试并行化它来中断引擎管理。
这是“并行”代码:
import numpy as np
from scipy.linalg import eig
from IPython import parallel
#create the matrices
matrix_size = 300
matrices = {}
for i in range(100):
matrices[i] = np.random.rand(matrix_size, matrix_size)
rc = parallel.Client()
lview = rc.load_balanced_view()
results = {}
#compute the eigenvalues
for i in range(len(matrices)):
asyncresult = lview.apply(eig, matrices[i], right=False)
results[i] = asyncresult
for i, asyncresult in results.iteritems():
results[i] = asyncresult.get()
非并行变体:
#no parallel
for i in range(len(matrices)):
results[i] = eig(matrices[i], right=False)
两者的 CPU 时间差异非常微妙。如果在特征值问题之上,并行化函数必须进行更多矩阵运算,它开始永远持续下去,即至少比非并行化变体长 5 倍。
我对特征值问题并不真正适合这种并行化是对的,还是我错过了重点?
非常感谢!
2013 年 7 月 29 日编辑;英国夏令时 12:20
按照 moarningsun 的建议,我尝试在eig
使用mkl.set_num_threads
. 对于 500×500 矩阵,最少 50 次重复设置如下:
No of. threads minimum time(timeit) CPU usage(Task Manager)
=================================================================
1 0.4513775764796151 12-13%
2 0.36869288559927327 25-27%
3 0.34014644287680085 38-41%
4 0.3380558903450037 49-53%
5 0.33508234276183657 49-53%
6 0.3379019065051807 49-53%
7 0.33858615048501406 49-53%
8 0.34488405094054997 49-53%
9 0.33380300334101776 49-53%
10 0.3288481198342197 49-53%
11 0.3512653110685733 49-53%
除了一个线程情况之外,没有实质性差异(也许 50 个样本有点小......)。我仍然认为我没有抓住重点,可以做很多事情来提高性能,但不确定如何做。这些是在启用了超线程的 4 核机器上运行的,提供 4 个虚拟内核。
感谢您的任何意见!