Я запускаю программу, которая сначала загружает 20 ГБ данных в память. Затем я буду выполнять N (> 1000) независимых задач, в которых каждый из них может использовать (только для чтения) часть данных 20 ГБ. Теперь я пытаюсь выполнить эти задачи с помощью многопроцессорности. Однако, как сообщает this answer, все глобальные переменные копируются для каждого процесса. В моем случае у меня недостаточно памяти для выполнения более 4 задач, так как моя память составляет всего 96 ГБ. Интересно, есть ли какое-либо решение этой проблемы, чтобы я мог полностью использовать все свои ядра, не потребляя слишком много памяти.многопроцессорное копирование глобальной переменной памяти
ответ
В linux разветвленные процессы имеют представление на родительском адресном пространстве с копией на запись. forking имеет легкий вес, и одна и та же программа работает как у родителя, так и у ребенка, за исключением того, что ребенок принимает другой путь выполнения. В качестве небольшого exmample,
import os
var = "unchanged"
pid = os.fork()
if pid:
print('parent:', os.getpid(), var)
os.waitpid(pid, 0)
else:
print('child:', os.getpid(), var)
var = "changed"
# show parent and child views
print(os.getpid(), var)
Результаты в
parent: 22642 unchanged
child: 22643 unchanged
22643 changed
22642 unchanged
Применяя это к многопроцессорной, в этом примере я загрузить данные в глобальную переменную. Поскольку python рассоливает данные, отправленные в пул процессов, я убеждаюсь, что он раскроет что-то маленькое, как индекс, и заставить работника получить глобальные данные.
import multiprocessing as mp
import os
my_big_data = "well, bigger than this"
def worker(index):
"""get char in big data"""
return my_big_data[index]
if __name__ == "__main__":
pool = mp.Pool(os.cpu_count())
for c in pool.imap_unordered(worker, range(len(my_big_data)), chunksize=1):
print(c)
В Windows нет модели fork-and-exec для запуска программ. Он должен запустить новый экземпляр интерпретатора python и клонировать все соответствующие данные для ребенка. Это тяжелый подъем!
Aha. Хорошо, ключ к пониманию того, что происходит, это копирование на запись; несколько вещей кажутся противоречивыми при чтении о 'mp', если у вас нет более глубокого понимания. Спасибо за это объяснение, upvote. Из любопытства я все еще вынужден использовать «Менеджеров» из-за Windows; в моем случае, это создало бы еще один 20-гигабайтный объект (так оригинал + 'Manager' = 40 ГБ), чтобы инициализировать общий ресурс? Документы предполагают, что процессы получают доступ к общему списку/dict через прокси-сервер к _Manager_, но я никогда не работал с достаточно большими данными в 'mp' для тестирования. – roganjosh
спасибо @tdelaney, это зависит от версий python (2.7 для моего случая) и способа реализации (pool.map, imap, imap_unordered)? – wh408
@whan - 'map' и' imap' оба ждут завершения всей обработки и возвращают результаты в том порядке, в котором они были отправлены. Если вам не нужен порядок возврата, 'imap_unordered' является более эффективным и будет использовать меньше памяти, если результаты будут большими. Многопроцессорность очень похожа на python 2.x и 3.x. 'map' и' imap_unordered' являются хорошими вариантами в зависимости от того, хотите ли вы упорядоченные результаты. – tdelaney
- 1. MATLAB: Копирование глобальной переменной для всех работников
- 2. Глобальный __syncthreads() после инициализации глобальной переменной памяти
- 3. Потребление глобальной переменной и локальной переменной памяти javascript
- 4. Многопроцессорное использование с использованием общей памяти
- 5. Ошибка глобальной структуры памяти
- 6. Почему многопроцессорное копирование моих данных, если я его не трогаю?
- 7. Изменение постоянной глобальной переменной
- 8. Потоки глобальной памяти и CUDA
- 9. Загрузка из глобальной памяти
- 10. Доступ к глобальной памяти
- 11. Распределение памяти глобальной структуры
- 12. Выделение глобальной памяти
- 13. Android Memory - Объявление глобальной переменной
- 14. Свойство глобальной переменной Node.js очищается
- 15. Копирование с переменной переменной
- 16. Многопроцессорное программирование
- 17. Многопроцессорное планирование
- 18. Модуль Python для глобальной оптимизации глобальной переменной
- 19. Влияние памяти на присвоение нового значения глобальной переменной
- 20. ошибка в динамическом распределении памяти внутри глобальной переменной
- 21. Обновление до члена глобальной переменной, не отражающегося в глобальной переменной
- 22. Как C++ различает вызов глобальной переменной и объявление глобальной переменной?
- 23. Использование глобальной переменной в функции
- 24. Определение глобальной переменной Сброс
- 25. Шаблон постоянной глобальной переменной
- 26. использование глобальной переменной
- 27. Создание глобальной переменной settimeout
- 28. Makefile целевой глобальной переменной
- 29. Ошибка глобальной переменной C++
- 30. Использование переменной как глобальной
Почему вы загружаете столько данных в память? Что вы делаете с данными? В идеале вы хотите загружать данные в мельчайшие возможные куски. – sytech
@sytech Это характер моей задачи. Я думал о загрузке только данных, необходимых в каждом процессе, но это приведет к загрузке одних и тех же данных несколько раз. – wh408
Таким образом, каждый процесс должен обрабатывать все данные, но делает ли он свою собственную вещь, а не возможность дублирования усилий? В этом случае вы можете попробовать поделиться данными в 'Manager.dict()' [здесь] (https://docs.python.org/2/library/multiprocessing.html#managers) или 'Manager.list () 'и порождаем несколько« Процессов ». Если все они выполняют одну и ту же задачу, вы можете обрезать данные и передать каждому процессу свой собственный кусок. Я не думаю, что вы можете принести больше процессов, чем ядра, и, похоже, вам нужны процессы '1000. – roganjosh