【发布时间】:2019-09-01 12:58:07
【问题描述】:
我有一个处理器密集型任务,需要 13-20 小时才能完成,具体取决于机器。似乎是通过多处理库进行并行化的明显选择。问题是......我产生的进程越多,相同的代码就越慢。
每次迭代的时间(即运行 sparse.linalg.cg 所需的时间):
183s 1 个进程
245s 2 个进程
312s 3 个进程
383s 4 个进程
当然,虽然 2 个进程在每次迭代中多花费 30% 多一点的时间,但它同时执行 2 个进程,所以它仍然稍微快一些。但我不希望实际的数学运算本身会变慢!这些计时器在多处理增加的任何开销之后才会启动。
这是我的代码的精简版。问题线是 sparse.linalg.cg 之一。 (我尝试过使用 MKL 与 OpenBLAS 之类的方法,并强制它们在单个线程中运行。还尝试手动生成进程而不是使用池。不走运。)
def do_the_thing_partial(iteration: int, iter_size: float, outQ : multiprocessing.Queue, L: int, D: int, qP: int, elec_ind: np.ndarray, Ic: int, ubi2: int,
K : csc_matrix, t: np.ndarray, dip_ind_t: np.ndarray, conds: np.ndarray, hx: float, dstr: np.ndarray):
range_start = ceil(iteration * iter_size)
range_end = ceil((iteration + 1) * iter_size)
for rr in range(range_start, range_end):
# do some things (like generate F from rr)
Vfull=sparse.linalg.cg(K,F,tol=1e-11,maxiter=1200)[0] #Solve the system
# do more things
outQ.put((rr, Vfull))
def do_the_thing(L: int, D: int, qP: int, elec_ind: np.ndarray, Ic: int, ubi2: int,
K : csc_matrix, t: np.ndarray, dip_ind_t: np.ndarray, conds: np.ndarray, hx: float, dstr: np.ndarray):
num_cores = cpu_count()
iterations_per_process = (L-1) / num_cores # 257 / 8 ?
outQ = multiprocessing.Queue()
pool = multiprocessing.Pool(processes=num_cores)
[pool.apply_async(do_the_thing_partial,
args=(i, iterations_per_process, outQ, L, D, qP, elec_ind, Ic, ubi2, K, t, dip_ind_t, conds, hx, dstr),
callback=None)
for i in range(num_cores)]
pool.close()
pool.join()
for res in outQ:
# combine results and return here
是我做错了什么,还是因为 sparse.linalg.cg 自身的优化而无法并行化?
谢谢!
【问题讨论】:
-
解释你是如何在进程之间拆分任务的。
cg正在迭代求解K*x=F。进程之间有什么不同? -
F 在“做一些事情”部分定义,使用 rr 计算。 rr 可能的值范围取决于哪个进程 例如,有 2 个进程: 进程 0:rr 在 0..127 范围内 进程 1:rr 在 128..255 范围内
标签: python python-3.x numpy scipy python-multiprocessing