ThreadPool and Pool for parallel processing
有没有一种方法可以通过指定要使用的CPU和内核数在python中同时使用ThreadPool和Pool来并行化循环?
例如,我将循环执行为:
1 2 3 4 5 6 7 8 9 10 11 12 | from multiprocessing.dummy import Pool as ThreadPool from tqdm import tqdm import numpy as np def my_function(x): return x + 1 pool = ThreadPool(4) my_array = np.arange(0,1e6,1) results = list(tqdm(pool.imap(my_function, my_array),total=len(my_array))) |
对于4核,但我也想将它们分散到多个CPU上,是否有一种简单的方法来适应代码?
您在核心和CPU之间感到困惑。通常,出于所有目的,两者都被认为是相同的(从现在开始,我们称它们为处理器)。
在python中创建线程池时,由于python中的全局解释器锁(GIL),这些线程是用户级线程,并且在同一处理器上运行。由于一次只能有一个线程控制python解释器。因此,使用(python)线程在数据密集型任务中没有任何真正的并发性。
如何解决呢?简单。生成在不同处理器上运行的多个python进程(每个进程都有自己的解释器)。这是使用multi processing(mp)模块的地方,从调用它的父python进程中产生多个进程。
您可以通过运行htop(在linux,mac上)并分析python进程数来验证这一点。如果是mp模块,它们都将具有与调用pool.map函数的父脚本相同的名称。
- 在8核心Mac上的代码计时:39.7秒
- 在同一台机器上此代码的时间:2.9s(请注意,我最多可以使用8个核,但出于比较目的,仅使用4个核)
下面是修改后的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | from multiprocessing.dummy import Pool as ThreadPool from tqdm import tqdm import numpy as np import time import multiprocessing as mp def my_function(x): return x + 1 pool = ThreadPool(4) my_array = np.arange(0,1e6,1) t1 = time.time() # results = list(tqdm(pool.imap(my_function, my_array),total=len(my_array))) pool = mp.Pool(processes=4) # Generally, set to 2*num_cores you have res = pool.map(my_function, my_array) print("Time taken =", time.time() - t1) |