Python multiprocessing执行CPU密集任务为何远慢于串行处理?
Python多进程CPU密集型任务效率异常问题分析
问题描述
我尝试通过CPU密集型任务对比Python multiprocessing模块的效率,测试结果却不符合预期:
串行任务实现及耗时
import multiprocessing import time v1 = [0] * 5000000 v2 = [0] * 5000000 def worker1(nums): global v1 for i in range(nums): v1[i] = i*i def worker2(nums): global v2 for i in range(nums): v2[i] = i*i*i start = time.time() worker1(5000000) worker2(5000000) end = time.time() print(end-start)
串行任务耗时约1秒。
多进程任务实现及耗时
import multiprocessing import time def worker1(nums,v1): for i in range(nums): v1[i] = i*i def worker2(nums,v2): for i in range(nums): v2[i] = i*i*i v1 = multiprocessing.Array('i',5000000) v2 = multiprocessing.Array('i',5000000) p1 = multiprocessing.Process(target=worker1, args = (5000000,v1)) p2 = multiprocessing.Process(target=worker2, args = (5000000,v2)) start = time.time() p1.start() p2.start() p1.join() p2.join() end = time.time() print(end-start)
多进程任务耗时约12秒。
明明多进程理论上应该比串行更快,即使有进程创建开销,也不该差这么多,请问是哪里操作错了?
问题原因及修正方案
核心原因
你的多进程实现慢的关键问题在于**multiprocessing.Array的性能损耗**。这个对象是基于共享内存的同步结构,每次对它的元素进行读写操作时,都会触发额外的锁机制和内存同步开销,远不如普通Python列表的直接内存访问高效。串行代码里用的是普通列表,而多进程里用了multiprocessing.Array,这才导致了耗时的巨大差异。
修正方法
避免在多进程任务中频繁操作共享内存对象,改为让子进程独立完成计算后返回结果,主进程再合并结果:
修正后的多进程代码
import multiprocessing import time def worker1(nums): v1 = [0] * nums for i in range(nums): v1[i] = i*i return v1 def worker2(nums): v2 = [0] * nums for i in range(nums): v2[i] = i*i*i return v2 if __name__ == "__main__": start = time.time() with multiprocessing.Pool(2) as pool: result1 = pool.apply_async(worker1, (5000000,)) result2 = pool.apply_async(worker2, (5000000,)) v1 = result1.get() v2 = result2.get() end = time.time() print(end-start)
这样修改后,多进程的耗时会接近串行的一半左右(取决于CPU核心数),符合预期。另外注意:在Windows系统下,多进程代码必须放在if __name__ == "__main__":块中,避免重复创建进程的潜在问题。
内容的提问来源于stack exchange,提问作者Satyam Rai
相关产品推荐
相关产品推荐

