我正在尝试应用多重处理来并行化我的代码。我大约有 2000项作品要完成。由于创建2000个并发进程不切实际,因此我使用python multiprocessing.pool API在管理任务队列时并行化工作。我尝试创建100名工人。但是要花几个小时才能完成,与顺序实施相比,这并不是什么大的收获。我的笔记本电脑有12个逻辑核心。然后,我尝试同时增加工作人员和工作。从技术上讲,每项工作都需要花费相同的时间,因为我每次只将一项工作分配给一名工人。但是我发现即使每件工作的工作量不变,整个过程的时间也会增加。 API出问题了吗?还是我做错了?有人可以为我提供2000年使用Python在最短时间内进行并行处理的可行解决方案吗?
P.S:由于代码实现问题,我无法使用多线程。
我的代码
inputListLen = 13
workerCount = 13
regressList = regressList[:inputListLen] # regressList has 2000 items
with Pool(processes=workerCount) as pool:
print(pool.map(runRegressWriteStatus, regressList))
结果
Input List Len | workers | Time(seconds)
1 | 1 | 4.5
2 | 2 | 4.9
3 | 3 | 5.4
4 | 4 | 5.6
5 | 5 | 6.3
6 | 6 | 7.2
7 | 7 | 8.3
8 | 8 | 9.6
9 | 9 | 10.0
10 | 10 | 10.7
11 | 11 | 11.6
12 | 12 | 11.8
13 | 13 | 13.3
答案 0 :(得分:1)
我认为您误会了几件事,并且对几件事的假设并不是很准确。正如我在Python multiprocessing: dealing with 2000 processes中提到的那样,您实际上可以与multiprocessing
并行运行的进程数取决于系统上具有的CPU核心数,并由它们控制。这是实际的物理核心,而不是启用超线程后看到的逻辑核心。
因此12个逻辑核心意味着6个物理核心,每个核心2个线程为您提供12个逻辑核心。因此,在任何时间点,您的内核都会看到12个逻辑内核,并尝试调度12个进程,但是系统只有6个物理内核,因此发生了很多上下文切换,使得它看起来好像有12个内核,但是在任何时间点实时不能超过6个进程,因为请记住您只有6个核心。
第二,Pool
的工作方式不同于Process
,而使用Process
则可以启动并行进程来执行可能彼此独立的任务。
Pool
具有不同的用途,使用Pool
对象创建一个pool
进程,然后将一个大任务/输入传递给它,然后将pool
传递给它将这个大任务/输入分成较小的任务/输入,并将其分配到processes
中,它们可以同时对较小的输入进行操作。
这是一个非常简单的示例,说明如何使用pool
。
import multiprocessing as mp
import time
def f(x):
res = 0
for i in range(x):
res += i ** 6
if __name__ == '__main__':
t1 = time.time()
# MP Pool creates 4 concurrent processes and run the same function with diffrent args, to achieve the parallel computation
po = mp.Pool(processes=4)
res = po.map(f, range(5000))
po.close()
po.join()
print('Parallel execution time taken = {}'.format(time.time() - t1))
t2 = time.time()
seq_res = list(map(f, range(5000)))
print('Sequential execution time taken = {}'.format(time.time() - t2))
(py37) rbhanot@rbhanotlinux ~/home » python 7-1.mppool.py
Parallel execution time taken = 0.91422438621521
Sequential execution time taken = 2.9315543174743652
(py37) rbhanot@rbhanotlinux ~/home »
如您所见,使用pool
并行执行所花的时间比顺序执行所花的时间少3倍。
现在我有8个逻辑核心,但我的机器上只有4个物理核心,并且我的内核最多只能一次调度4个进程,因此创建一个包含4个以上进程的池不会有任何区别,这是一个证明。
与7个进程池一起运行时
Parallel execution time taken = 0.9177846908569336
在包含12个进程的池中运行
Parallel execution time taken = 0.9213907718658447
在包含2个进程的池中运行
Parallel execution time taken = 1.712911605834961