У меня есть три больших списка. Первый содержит битрейты (модуль bitarray 0.8.0), а два других содержат массивы целых чисел.
l1=[bitarray 1, bitarray 2, ... ,bitarray n]
l2=[array 1, array 2, ... , array n]
l3=[array 1, array 2, ... , array n]
Эти структуры данных занимают довольно много ОЗУ (~ 16 ГБ).
Если я запустил 12 подпроцессов, используя:
multiprocessing.Process(target=someFunction, args=(l1,l2,l3))
Означает ли это, что l1, l2 и l3 будут скопированы для каждого подпроцесса или будут ли подпроцессы разделять эти списки? Или, чтобы быть более прямым, я буду использовать 16 ГБ или 192 ГБ ОЗУ?
someFunction будет считывать некоторые значения из этих списков и затем выполняет некоторые вычисления на основе прочитанных значений. Результаты будут возвращены родительскому процессу. Списки l1, l2 и l3 не будут изменены некоторой функцией.
Поэтому я бы предположил, что подпроцессы не нужны и не будут копировать эти огромные списки, но вместо этого просто передадут их родителям. Это означает, что в программе потребуется 16 ГБ оперативной памяти (независимо от того, сколько подпроцессов я запускаю) из-за подхода copy-on-write под linux? Я исправляю или мне не хватает чего-то, что приведет к копированию списков?
ИЗМЕНИТЬ: Я все еще смущен, прочитав немного больше по этому вопросу. С одной стороны, Linux использует copy-on-write, что должно означать, что данные не копируются. С другой стороны, доступ к объекту изменит значение ref-count (я все еще не уверен, почему и что это значит). Тем не менее, будет ли скопирован весь объект?
Например, если я определяю someFunction следующим образом:
def someFunction(list1, list2, list3):
i=random.randint(0,99999)
print list1[i], list2[i], list3[i]
Будет ли использование этой функции означать, что l1, l2 и l3 будут полностью скопированы для каждого подпроцесса?
Есть ли способ проверить это?
EDIT2 После прочтения немного больше и мониторинга общего использования памяти системы во время работы подпроцессов кажется, что целые объекты действительно копируются для каждого подпроцесса. И это похоже на подсчет ссылок.
Подсчет ссылок для l1, l2 и l3 фактически не используется в моей программе. Это связано с тем, что l1, l2 и l3 будут сохраняться в памяти (без изменений), пока не завершится родительский процесс. Нет необходимости освобождать память, используемую этими списками, до тех пор. На самом деле я точно знаю, что счетчик ссылок останется выше 0 (для этих списков и каждого объекта в этих списках) до выхода программы.
Итак, теперь возникает вопрос, как я могу убедиться, что объекты не будут скопированы в каждый подпроцесс? Могу ли я отключить подсчет ссылок для этих списков и каждого объекта в этих списках?
EDIT3 Еще одно примечание. Подпроцессам не нужно изменять l1
, l2
и l3
или любые объекты в этих списках. Подпроцессы должны иметь возможность ссылаться на некоторые из этих объектов, не вызывая копирование памяти для каждого подпроцесса.