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:
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:
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
.
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:
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.