J'ai trois grandes listes. La première contient des tableaux de bits (module bitarray 0.8.0) et les deux autres des tableaux d'entiers.
l1=[bitarray 1, bitarray 2, ... ,bitarray n]
l2=[array 1, array 2, ... , array n]
l3=[array 1, array 2, ... , array n]
Ces structures de données occupent une grande partie de la RAM (~16GB au total).
Si je lance 12 sous-processus en utilisant :
multiprocessing.Process(target=someFunction, args=(l1,l2,l3))
Cela signifie-t-il que l1, l2 et l3 seront copiés pour chaque sous-processus ou que les sous-processus partageront ces listes ? Ou, pour être plus direct, est-ce que j'utiliserai 16 Go ou 192 Go de RAM ?
someFunction lira certaines valeurs de ces listes et effectuera ensuite certains calculs sur la base des valeurs lues. Les résultats seront renvoyés au processus parent. Les listes l1, l2 et l3 ne seront pas modifiées par someFunction.
Par conséquent, je suppose que les sous-processus n'ont pas besoin et ne copient pas ces énormes listes, mais les partagent simplement avec le parent. Cela signifie que le programme prendrait 16 Go de RAM (quel que soit le nombre de sous-processus que je lance) en raison de l'approche "copy-on-write" sous Linux ? Ai-je raison ou ai-je manqué quelque chose qui ferait que les listes seraient copiées ?
EDITAR : Je suis toujours confus, après avoir lu un peu plus sur le sujet. D'un côté, Linux utilise le copy-on-write, ce qui devrait signifier qu'aucune donnée n'est copiée. D'autre part, l'accès à l'objet changera son ref-count (je ne sais toujours pas pourquoi et ce que cela signifie). Malgré cela, l'objet entier sera-t-il copié ?
Par exemple, si je définis une certaineFonction comme suit :
def someFunction(list1, list2, list3):
i=random.randint(0,99999)
print list1[i], list2[i], list3[i]
L'utilisation de cette fonction signifie-t-elle que l1, l2 et l3 seront entièrement copiés pour chaque sous-processus ?
Y a-t-il un moyen de vérifier cela ?
EDIT2 Après avoir lu un peu plus et surveillé l'utilisation totale de la mémoire du système pendant l'exécution des sous-processus, il semble que des objets entiers soient effectivement copiés pour chaque sous-processus. Et cela semble être dû au comptage des références.
Le comptage des références pour l1, l2 et l3 est en fait inutile dans mon programme. En effet, les listes l1, l2 et l3 seront conservées en mémoire (sans modification) jusqu'à la sortie du processus parent. Il n'y a pas besoin de libérer la mémoire utilisée par ces listes jusque là. En fait, je sais avec certitude que le nombre de références restera supérieur à 0 (pour ces listes et chaque objet de ces listes) jusqu'à ce que le programme se termine.
La question est donc la suivante : comment puis-je m'assurer que les objets ne seront pas copiés dans chaque sous-processus ? Puis-je désactiver le comptage des références pour ces listes et chaque objet de ces listes ?
EDIT3 Une remarque supplémentaire. Les sous-processus n'ont pas besoin de modifier l1
, l2
y l3
ou tout autre objet de ces listes. Les sous-processus doivent seulement pouvoir faire référence à certains de ces objets sans que la mémoire soit copiée pour chaque sous-processus.