1

当我在 56 核机器上使用进程池执行器触发它的并行实例时,我观察到 python 脚本的执行时间增加了。脚本 abc.py 导入一个沉重的 python 库,大约需要 1 秒。

time python ~/abc.py

real 0m0.846s
user 0m0.620s
sys 0m0.078s

测试方法

import shlex
from subprocess import Popen, PIPE

def test():
    command = "python /u/deeparora/abc.py"
    p = Popen(shlex.split(command), stdout=PIPE, stderr=PIPE)
    p.wait(timeout=None)

下面的代码也需要 1 秒,这是预期的

串行执行

import concurrent.futures

pool = ProcessPoolExecutor(max_workers=1)
futures = []
 
for index in range(0, 1):
    futures.append(pool.submit(test))

for future in concurrent.futures.as_completed(futures):
    pass

但是下面的代码在 56 核机器上执行需要 5 秒

并行执行

import concurrent.futures

pool = ProcessPoolExecutor(max_workers=50)
futures = []
 
for index in range(0, 50):
    futures.append(pool.submit(test))

for future in concurrent.futures.as_completed(futures):
    pass

我检查了进程日志中的执行时间,可以注意到现在脚本(abc.py)的执行时间也从 1 秒增加到了 4 秒。有人可以帮我理解这种行为吗?

4

1 回答 1

-1

检查图表在这里 我试图运行它。并发现了有趣的结果。

  1. 当给定的功能太简单时。那么函数执行时间<多池创建时间。所以增加更多的工人会增加总时间。

  2. 要验证这一点,请检查下面的 sleep(0.001) 实验。

  3. 从图表中,当我增加工人时,首先总时间减少,但在某个点之后,总时间开始增加,因为创建和关闭工人的成本高于计算时间本身。

    from concurrent.futures import ProcessPoolExecutor
    from time import sleep, time
     
    values = [3,4,5,6] * 200
    def cube(x):
        sleep(0.001)
        return x*x*x
    
    times = []
    total_threds = [i for i in range(1, 20)]
    for num_tread in range(1, 20):
        print(f'Processing thread: {num_tread}')
        st_time = time()
        
        with ProcessPoolExecutor(max_workers=num_tread) as exe:
            exe.submit(cube,2)
    
            # Maps the method 'cube' with a iterable
            result = exe.map(cube,values)
            
        
        end_time = time()[enter image description here][1]
        times.append(end_time - st_time)
    
    plt.plot(total_threds, times)
    plt.title('Number of threads vs Time taken to Run')
    plt.xlabel('Number of Threads')
    plt.ylabel('Time taken in ms')

在此处检查图表

于 2022-01-10T12:09:14.777 回答