Bagaimana cara membuat profil beberapa subproses menggunakan multiprosesing Python dan memory_profiler?

Saya memiliki utilitas yang memunculkan banyak pekerja menggunakan modul Python multiprocessing, dan saya' Saya ingin dapat melacak penggunaan memori mereka melalui utilitas memory_profiler yang luar biasa, yang melakukan semua yang saya inginkan - khususnya pengambilan sampel penggunaan memori dari waktu ke waktu dan merencanakan hasil akhir (saya tidak peduli dengan pembuatan profil memori baris demi baris untuk pertanyaan ini).

Untuk menyiapkan pertanyaan ini, saya telah membuat versi skrip yang lebih sederhana, yang memiliki fungsi pekerja yang mengalokasikan memori mirip dengan contoh diberikan di perpustakaan memory_profiler. Pekerjanya adalah sebagai berikut:

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

Diberikan beban kerja berurutan sebanyak 4 orang pekerja sebagai berikut :

if __name__ == '__main__':
    worker(5, 5, X6)
    worker(5, 2, X7)
    worker(5, 5, X6)
    worker(5, 2, X7)

Menjalankan mprof yang dapat dieksekusi untuk membuat profil skrip saya membutuhkan waktu 70 detik agar setiap pekerja dijalankan satu demi satu. Scriptnya, jalankan sebagai berikut:

$ mprof run python myscript.py

Menghasilkan grafik penggunaan memori berikut:

Pekerja Penghasil Memori Berurutan

Menempatkan pekerja-pekerja ini secara paralel dengan multiprocessing berarti skrip akan selesai sama lambatnya dengan pekerja paling lambat (25 detik). Skrip itu adalah sebagai berikut:

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]

Memory profiler memang berfungsi, atau setidaknya tidak ada error saat menggunakan mprof namun hasilnya agak aneh:

masukkan deskripsi gambar di sini

Sekilas tentang Activity Monitor menunjukkan bahwa sebenarnya ada 6 proses Python, satu untuk mprof, satu untuk python myscript.py, dan satu lagi untuk setiap subproses pekerja. Tampaknya mprof hanya mengukur penggunaan memori untuk proses python myscript.py.

Proses Python di Monitor Aktivitas

Pustaka memory_profiler sangat dapat disesuaikan, dan saya cukup yakin bahwa saya dapat menangkap memori setiap proses dan mungkin menuliskannya ke file log terpisah dengan menggunakan pustaka itu sendiri. Saya hanya tidak yakin harus mulai dari mana atau bagaimana mendekati tingkat penyesuaian tersebut.

EDIT

Setelah membaca skrip mprof saya menemukan flag -C yang merangkum penggunaan memori dari semua proses anak (bercabang). Hal ini menghasilkan grafik (yang jauh lebih baik) sebagai berikut:

Pekerja Multiproses dengan Bendera Sertakan Anak

Namun yang saya cari adalah penggunaan memori setiap subproses dari waktu ke waktu sehingga saya dapat memplot semua pekerja (dan master) pada grafik yang sama. Ide saya adalah agar setiap subproses memory_usage ditulis ke file log yang berbeda, yang kemudian dapat saya visualisasikan.


person bbengfort    schedule 13.07.2016    source sumber
comment
Pertanyaan ini sedang didiskusikan dengan pengembang di GitHub di github.com/fabianp/memory_profiler/issues/118 jika ada yang tertarik.   -  person bbengfort    schedule 16.07.2016


Jawaban (1)


Mulai hari ini, fitur baru telah ditambahkan ke perpustakaan profiler memori yang melakukan hal ini. Jika Anda memerlukan fungsi ini, perbarui terlebih dahulu memory_profiler sebagai berikut:

$ pip install -U memory_profiler 

Ini harus menginstal profiler memori rilis v0.44. Untuk memeriksa apakah ini masalahnya, gunakan perintah bantuan pada tindakan yang dijalankan:

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

Jika Anda melihat bendera -M maka Anda siap berangkat!

Anda kemudian dapat menjalankan skrip Anda sebagai berikut:

$ mprof run -M python myscript.py
$ mprof plot 

Dan Anda harus mendapatkan gambar seperti ini:

mprof melacak proses anak individual

Perhatikan bahwa jika Anda juga menggunakan flag --include-children, memori proses utama akan menjadi total penggunaan memori semua anak dan main, yang juga merupakan plot yang berguna.

person bbengfort    schedule 22.03.2017
comment
terima kasih khusus kepada @fabian-pedregosa yang telah membantu mewujudkan hal ini! - person bbengfort; 22.03.2017
comment
Bagaimana dengan mengaktifkan stempel waktu dan dekorator @profile dalam mode ini? Apa itu mungkin? - person petroslamb; 01.06.2017
comment
Saya tidak yakin apa yang Anda maksud dengan mengaktifkan stempel waktu? Saya pikir ini dapat dilakukan dengan dekorator @profile, ia menggunakan argumen yang sama. - person bbengfort; 05.06.2017
comment
Sayangnya saya tidak bisa membuatnya berfungsi. Silakan lihat github.com/fabianp/memory_profiler/issues/148 - person petroslamb; 06.06.2017
comment
Ah, ya, saya mengerti masalahnya -- itu adalah laporan bug yang sangat bagus. Sayangnya masalah acar muncul di mana-mana ketika berhadapan dengan berbagai jenis pembuatan profil multiproses. Maaf tentang itu. - person bbengfort; 07.06.2017
comment
apakah ada cara untuk memberi nama pada proses anak? child-n tidak terlalu jelas :) - person Alon Gouldman; 07.04.2020
comment
Akan sangat bagus jika ada cara - saya pikir Anda mungkin harus mendalami detail cprofile untuk melihat apakah ada cara untuk melakukan itu. - person bbengfort; 07.04.2020
comment
@ fabian-pedregosa Bisakah kami menyimpan plot ini secara otomatis? - person Pe Dro; 03.06.2020
comment
Saya menemukan paket TAMPPA untuk menyimpan hasil memory-profiler dan line-profiler sebagai csv. .. bagus untuk digunakan di masa depan :) Semoga membantu - person Pe Dro; 29.08.2020