Parallel execution of a list of functions

后端 未结 2 1196
南方客
南方客 2021-01-25 06:37

So using the multiprocess module it is easy to run a function in parallel with different arguments like this:

from multiprocessing import Pool

def f(x):
    ret         


        
相关标签:
2条回答
  • 2021-01-25 07:06

    You can get a tuple returned. This could be done quite easily and in a very compact way using the lightweight module: joblib. I recommend joblib because it is lightweight

    from joblib import Parallel, delayed
    import multiprocessing
    import timeit
    
    
    # Implementation 1
    def f(x):    
        return x**2, x**3 + 2
    
    
    #Implementation 2 for a more sophisticated second or more functions
    def g(x):
        return  x**3 + 2
    
    
    def f(x):    
        return x**2, g(x)
    
    
    if __name__ == "__main__":
      inputs = [i for i in range(32)]
      num_cores = multiprocessing.cpu_count()
      t1 = timeit.Timer()
      result = Parallel(n_jobs=num_cores)(delayed(f)(i) for i in inputs)
      print(t1.timeit(1)) 
    

    Using multiprocessing.Pool as you already have in the question

    from multiprocessing import Pool, cpu_count
    import timeit
    
    
    def g(x):
        return x**3 + 2
    
    
    def f(x):    
        return x**2, g(x)
    
    if __name__ == "__main__":
      inputs = [i for i in range(32)]
      num_cores = cpu_count()
      p = Pool(num_cores)
      t1 = timeit.Timer()
      result = p.map(f, inputs)
      print(t1.timeit(1))
      print(result)    
    

    Example Output:

    print(result)
    
    [(0, 2), (1, 3), (4, 10), (9, 29), (16, 66), (25, 127), (36, 218), (49, 345), 
    (64, 514), (81, 731), (100, 1002), (121, 1333), (144, 1730), (169, 2199), 
    (196, 2746), (225, 3377), (256, 4098), (289, 4915), (324, 5834), (361, 6861), 
    (400, 8002), (441, 9263), (484, 10650), (529, 12169), (576, 13826), (625, 
    15627), (676, 17578), (729, 19685), (784, 21954), (841, 24391), (900, 27002), 
    (961, 29793)]
    
    print(t1.timeit(1))
        5.000001692678779e-07         #(with 16 cpus and 64 Gb RAM) 
    

    for: inputs = range(2000), it took the time: 1.100000190490391e-06

    0 讨论(0)
  • 2021-01-25 07:18

    You can use Pool.apply_async() for that. You bundle up tasks in the form of (function, argument_tuple) and feed every task to apply_async().

    from multiprocessing import Pool
    from itertools import repeat
    
    
    def f(x):
        for _ in range(int(50e6)): # dummy computation
            pass
        return x ** 2
    
    
    def g(x):
        for _ in range(int(50e6)): # dummy computation
            pass
        return x ** 3
    
    
    def parallelize(n_workers, functions, arguments):
        # if you need this multiple times, instantiate the pool outside and
        # pass it in as dependency to spare recreation all over again
        with Pool(n_workers) as pool:
            tasks = zip(functions, repeat(arguments))
            futures = [pool.apply_async(*t) for t in tasks]
            results = [fut.get() for fut in futures]
        return results
    
    
    if __name__ == '__main__':
    
        N_WORKERS = 2
    
        functions = f, g
        results = parallelize(N_WORKERS, functions, arguments=(10,))
        print(results)
    

    Example Output:

    [100, 1000]
    
    Process finished with exit code 0
    
    0 讨论(0)
提交回复
热议问题