Как профилировать несколько подпроцессов с помощью Python multiprocessing и Memory profiler?
у меня есть утилита, которая порождает несколько рабочих с помощью Python multiprocessing
модуль, и я хотел бы иметь возможность отслеживать их использование памяти через отличный memory_profiler
утилита, которая делает все, что я хочу, - в частности, выборка использования памяти с течением времени и построение конечного результата (Меня не волнует профилирование строчной памяти для этого вопроса).
чтобы настроить этот вопрос, я создал более простую версию скрипт, который имеет рабочую функцию, которая выделяет память, подобную пример передана в memory_profiler
библиотека. Рабочий такой:
import time
X6 = 10 ** 6
X7 = 10 ** 7
def worker(num, wait, amt=X6):
"""
A function that allocates memory over time.
"""
frame = []
for idx in range(num):
frame.extend([1] * amt)
time.sleep(wait)
del frame
учитывая последовательную рабочую нагрузку 4 работников следующим образом:
if __name__ == '__main__':
worker(5, 5, X6)
worker(5, 2, X7)
worker(5, 5, X6)
worker(5, 2, X7)
под управлением mprof
исполняемый файл для профилирования моего скрипта занимает 70 секунд, когда каждый работник запускается один за другим. Скрипт, работает следующим образом:
$ mprof run python myscript.py
производит следующее использование памяти график:
эти рабочие идут параллельно с multiprocessing
означает, что сценарий завершится так же медленно, как самый медленный рабочий (25 секунд). Этот сценарий выглядит следующим образом:
import multiprocessing as mp
if __name__ == '__main__':
pool = mp.Pool(processes=4)
tasks = [
pool.apply_async(worker, args) for args in
[(5, 5, X6), (5, 2, X7), (5, 5, X6), (5, 2, X7)]
]
results = [p.get() for p in tasks]
профайлер памяти действительно работает, или, по крайней мере, нет ошибок при использовании mprof
но результаты немного странные:
быстрый взгляд на монитор активности показывает, что на самом деле есть 6 процессов Python, один для mprof
для python myscript.py
и затем по одному для каждого рабочего подпроцесса. Оказывается, что mprof
измеряет только использование памяти для
1 ответов
на сегодняшний день в библиотеку профилировщика памяти добавлена новая функция, которая делает именно это. Если вам нужна эта функциональность, сначала обновите memory_profiler следующим образом:
$ pip install -U memory_profiler
Это должно установить v0.44 выпуск профилировщика памяти. Чтобы проверить, что это так, используйте команду help в действии run:
mprof run --help
Usage: mprof run [options]
Options:
--version show program's version number and exit
-h, --help show this help message and exit
--python Activates extra features when the profiling executable
is a Python program (currently: function
timestamping.)
--nopython Disables extra features when the profiled executable
is a Python program (currently: function
timestamping.)
-T INTERVAL, --interval=INTERVAL
Sampling period (in seconds), defaults to 0.1
-C, --include-children
Monitors forked processes as well (sum up all process
memory)
-M, --multiprocess Monitors forked processes creating individual plots
for each child
если вы видите -M
флаг, то вы хорошо идти!
затем вы можете запустить ваш скрипт следует:
$ mprof run -M python myscript.py
$ mprof plot
и вы должны получить фигуру, которая выглядит так:
обратите внимание, что если вы используете --include-children
флаг также, основная память процесса будет общим использованием памяти всех детей и main, что также является полезным сюжетом.