I've got a program using the multiprocessing library to compute some stuff. There are about 10K inputs to compute, each of them taking between 0.2 second and 10 seconds.
My current approach uses a Pool:
# Inputs
signals = [list(s) for s in itertools.combinations_with_replacement(possible_inputs, 3)]
# Compute
with mp.Pool(processes = N) as p:
p.starmap(compute_solutions, [(s, t0, tf, folder) for s in signals])
print (" | Computation done.")
I've noticed that on the 300 / 400 last inputs to check, the program became a lot slower. My question is: how does the Pool
and the starmap()
behave?
Fro my observation, I believe that if I got 10K inputs and N = 4
(4 processes), then the 2 500 first inputs are assigned to the first process, the 2 500 next to the second, ... and each process treats its inputs in a serial fashion.
Which means that if some processes have cleared the Queue before others, they do not get new tasks to perform.
Is this correct?
If this is correct, how can I have a smarter system which could be represented with this pseudo-code:
workers = Initialize N workers
tasks = A list of the tasks to perform
for task in tasks:
if a worker is free:
submit task to this worker
else:
wait
Thanks for the help :)
N.B: What is the difference between the different map function. I believe map()
, imap_unordered()
, imap
, starmap
exists.
What are the differences between them and when should we use one or the other?