J'ai une classe qui stocke un grand tableau numpy
dans l'état. Cela provoque multiprocessing.Pool
à devenir extrêmement lent. Voici un MRE:Multiprocessing avec grand tableau en état
from multiprocessing import Pool
import numpy
import time
from tqdm import tqdm
class MP(object):
def __init__(self, mat):
self.mat = mat
def foo(self, x):
time.sleep(1)
return x*x + self.mat.shape[0]
def bar(self, arr):
results = []
with Pool() as p:
for x in tqdm(p.imap(self.foo, arr)):
results.append(x)
return results
if __name__ == '__main__':
x = numpy.arange(8)
mat = numpy.random.random((1,1))
h = MP(mat)
res = h.bar(x)
print(res)
J'ai 4 cœurs sur CPU, ce qui signifie que ce code devrait (et ne) courir dans environ 2 secondes. (Le tqdm
montre les 2 secondes comme une barre de progression, ce n'est pas vraiment nécessaire dans cet exemple). Cependant, dans le programme principal, si je fais mat = numpy.random.random((10000,10000))
, il faut une éternité pour fonctionner. Je suppose que c'est parce que Pool
fait des copies de mat
pour chaque travailleur, mais je ne suis pas sûr comment cela fonctionne parce que mat
est dans l'état de la classe, et non directement impliqué dans l'appel imap
. Donc, mes questions sont:
- Pourquoi ce comportement se produit-il? (c'est-à-dire, comment
Pool
fonctionne-t-il dans une classe? Qu'est-ce qu'elle contient exactement? Quelles sont les copies effectuées et lesquelles sont transmises par référence?) - Qu'est-ce qu'une solution de contournement viable à ce problème?
Modifier: modification foo
à utiliser mat
, qui est plus représentatif de mon vrai problème.
Quelle est la taille de 'x' dans votre programme principal? –
Dans votre programme principal, la fonction que vous transmettez à 'p.imap' doit-elle être une méthode de' MP', ou peut-elle être une fonction non liée? –
@JeremyMcGibbon Bon point. Je suppose que mon exemple n'était pas une bonne représentation de mon vrai problème. Donc, la fonction doit être une méthode de 'MP', car la fonction lit réellement' mat'. – ved