假设我们有一个递归关系
A[0] = a
A[i+1] = f(A[i],c)
其中c是参数,f
是某个函数,比如说
def f(x, c):
return sin(x) + c
假设对于给定的a
,我们要评估A[i] for i in range(0,n)
c in Cs = [c[j] for j in range(0, m)]
,其中n
和m
相当大。
用几句话提问:我应该为每个i使用多线程来理解每个c或列表。
让我解释一下。我正在考虑以下两种方法:
方法1:
将A[i]
存储在2D数组中,每行包含固定c [i]的序列值。但是以列主要顺序存储数组,使得常量i的A [i]是连续的。
然后使用list comprehension来计算它们
for i in range(0,n):
A[:,i+1] = [f(A[i],c) for c in Cs]
方法2:
如前所述将序列存储在2D数组中,但这次按行主要顺序存储。
有一个给定行的函数用给定c的序列值填充它。
def sequence(j):
A[j, 0] = a
for i in range(0, n - 1):
A[j, i+1] = f(A[j, i], Cs[j])
然后使用sequence
调用j
在不同的线程进程中的不同multiprocessing.Pool
。
我更喜欢这两种方法中的哪一种?
实验:
我尝试了以下测试
import numpy
from multiprocessing.dummy import Pool
from multiprocessing import cpu_count
import time
def func(x):
N = 400
A = numpy.array([[i*j for i in range(0,N)] for j in range(0, N)])
h = numpy.array([x for i in range(0, N)])
y = numpy.dot(A, h.transpose())
return y[-1]
start_time = time.time()
def multiproc():
print('Multiple processes')
print(cpu_count())
mypool = Pool(cpu_count())
print(mypool.map(func, [i for i in range(0,100)]))
def multiproc2():
print('Multiple processes 2')
pool = Pool(cpu_count())
res = numpy.empty(100)
for i in range(0,100):
res[i] = pool.apply_async(func, (i,)).get()
pool.close()
pool.join()
print(res)
def singleproc():
for i in range(0,100):
print(func(i))
print('Single process')
funcs = [multiproc, singleproc, multiproc2]
funcs[1]()
print("%.6f seconds" % (time.time() - start_time))
更改funcs[1]()
或funcs[0]()
的来电funcs[2]()
,我们在每种情况下都会得到相同的时间。
答案 0 :(得分:1)
我更喜欢使用Pool包装器,因为它看起来似乎更好的线程方法。试试这个:
from multiprocessing import Pool
import numpy as np
def f(x, c):
return sin(x)+c
A = np.zeros(shape=(m, n))
for i in range(n-1):
pool = Pool()
res = []
for j in range(m):
res.append(pool.apply_async(f, (A[i, j], Cs[j])))
pool.close()
pool.join()
for j in range(m):
A[i+1, j] = res[j].get()
你可以随时计算两种方法,看看哪一种方法最快:
import time
start_time = time.time()
# your code
print("%.6f seconds" % (time.time() - start_time))
这不是很准确,但它应该足以达到您的目的。