我正在尝试将矩阵的每一列乘以向量元素。
我有一个可以正常工作的串行解决方案。
for i in range(0,temp.shape[0]):
for j in range(0,temp.shape[1]):
temp[i,j] = temp[i,j] * h[i,0]
下面是适用于我正在尝试做的事情的并行解决方案,但不会返回与上述代码相同的矩阵。
def mv_mult(start_col,end_col,M,V):
for i in range(0,M.shape[0]):
for j in range(start_col,end_col):
M[i,j] = M[i,j] * V[i,0]
num_threads = multiprocessing.cpu_count()
threads = []
extra = temp.shape[1] % num_threads
start_col = 0
jump = temp.shape[1] / num_threads
for i in range(0,num_threads):
print 'starting thread ', i
if (i < extra)
args = start_col, start_col+jump+1,temp,h
p = multiprocessing.Process(target=mv_mult,args=args)
p.start()
threads.append(p)
start_col += jump+1
else:
args = start_col, start_col+jump,temp,h
p = multiprocessing.Process(target=mv_mult,args=args)
p.start()
threads.append(p)
start_col += jump
for i in threads:
i.join()
我对 Python 比较陌生,但据我所知,一切都是通过引用传递的,因此传递给每个新进程的临时矩阵是同一个对象,所以它应该与串行解决方案一样工作,减去事实它按列拆分。
关于为什么它不起作用的任何想法?
请您参考如下方法:
这只是 numpy 的 multiply 操作:
import numpy
a = numpy.matrix(numpy.ones((5,5)))
b = numpy.arange(5).reshape(5,1)
print a
print b
#[[ 1. 1. 1. 1. 1.]
# [ 1. 1. 1. 1. 1.]
# [ 1. 1. 1. 1. 1.]
# [ 1. 1. 1. 1. 1.]
# [ 1. 1. 1. 1. 1.]]
#[[0]
# [1]
# [2]
# [3]
# [4]]
c = numpy.multiply(a,b)
print c
#[[ 0. 0. 0. 0. 0.]
# [ 1. 1. 1. 1. 1.]
# [ 2. 2. 2. 2. 2.]
# [ 3. 3. 3. 3. 3.]
# [ 4. 4. 4. 4. 4.]]
(请注意,在您的串行版本中,您乘以行,而不是列)。
将此时间与您的串行版本进行比较:
#!/usr/bin/env python
import numpy
import numpy.random
import numpy.linalg
import sys
import time
def init(n):
a = numpy.matrix(numpy.random.rand(n,n))
b = numpy.random.rand(n,1)
b = b.reshape((n,1))
return a,b
def np_mult(a, b):
c = numpy.multiply(a,b)
return c
def manual_mult(a,b):
c = numpy.matrix(numpy.zeros_like(a))
for i in range(0,a.shape[0]):
for j in range(0,a.shape[1]):
c[i,j] = a[i,j] * b[i]
return c
def main(argv=None):
if argv is None:
argv = sys.argv
n = int(argv[1])
niters = int(argv[2])
a,b = init(n)
start = time.time()
for i in xrange(niters):
cnp = np_mult(a,b)
end = time.time()
nptime = (end-start)/niters
print 'Numpy: ', nptime
start = time.time()
for i in xrange(niters):
cm = manual_mult(a,b)
end = time.time()
manualtime = (end-start)/niters
print 'Manual: ', manualtime
print 'Speed difference = ', manualtime/nptime
print 'Diff = ', numpy.linalg.norm(cm - cnp)/numpy.linalg.norm(cnp)
return 0
if __name__ == "__main__":
sys.exit(main())
运行一些小尺寸会得到:
$ ./mult.py 50 5
Numpy: 3.48091125488e-05
mManual: 0.021101808548
Speed difference = 606.215068493
Diff = 0.0
$ ./mult.py 100 5
Numpy: 6.59942626953e-05
Manual: 0.0830503940582
Speed difference = 1258.44869942
Diff = 0.0
$ ./mult.py 500 5
Numpy: 0.000931406021118
Manual: 2.08903641701
Speed difference = 2242.88481032
Diff = 0.0
速度差异使您可以通过并行性弥补的任何事情都相形见绌。
