2016-07-13 21 views
7

मेरे पास एक उपयोगिता है जो पाइथन multiprocessing मॉड्यूल का उपयोग करके कई श्रमिकों को जन्म देती है, और मैं उत्कृष्ट memory_profiler उपयोगिता के माध्यम से अपने मेमोरी उपयोग को ट्रैक करने में सक्षम होना चाहता हूं, जो मैं चाहता हूं सब कुछ करता है - विशेष रूप से समय के साथ स्मृति उपयोग का नमूनाकरण और साजिश अंतिम परिणाम (मैं इस प्रश्न के लिए लाइन-दर-लाइन मेमोरी प्रोफाइलिंग से चिंतित नहीं हूं)।पायथन मल्टीप्रोसेसिंग और memory_profiler का उपयोग करके एकाधिक उपप्रोसेसेस को कैसे प्रोफाइल करें?

इस प्रश्न को सेटअप करने के लिए, मैंने स्क्रिप्ट का एक सरल संस्करण बनाया है, जिसमें एक कार्यकर्ता फ़ंक्शन है जो memory_profiler लाइब्रेरी में दिए गए example के समान स्मृति आवंटित करता है। कार्यकर्ता इस प्रकार है:

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 सेकंड चल रहा है। स्क्रिप्ट, के रूप में चलाने इस प्रकार है:

Sequential Memory Generating Workers

होने इन कर्मचारियों multiprocessing के साथ समानांतर में जाना का मतलब है कि स्क्रिप्ट धीमी कार्यकर्ता के रूप में के रूप में धीमी गति से खत्म हो जाएगा:

$ mprof run python myscript.py 

निम्नलिखित स्मृति उपयोग ग्राफ का उत्पादन (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 का उपयोग कर रहे हैं, लेकिन परिणाम थोड़ा अजीब हैं:: यह स्क्रिप्ट इस प्रकार है

enter image description here

पर एक त्वरित दृष्टि गतिविधि मॉनिटर दिखाता है कि वास्तव में 6 पायथन प्रक्रियाएं हैं, mprof एक python myscript.py के लिए एक और फिर प्रत्येक कार्यकर्ता उपप्रजाति के लिए एक है। ऐसा लगता है कि mprof केवल python myscript.py प्रक्रिया के लिए स्मृति उपयोग को माप रहा है।

Python Processes in Activity Monitor

memory_profiler पुस्तकालय उच्च अनुकूलन योग्य है, और मैं बहुत विश्वास है कि मैं प्रत्येक प्रक्रिया की स्मृति को पकड़ने और संभवतः लॉग फ़ाइलें अलग करने के लिए पुस्तकालय खुद का उपयोग करके उन्हें बाहर लिखने के लिए सक्षम होना चाहिए हूँ। मुझे यकीन नहीं है कि कहां से शुरू करना है या अनुकूलन के उस स्तर तक कैसे पहुंचे।

संपादित

mprof स्क्रिप्ट मैं -C ध्वज जो सभी बच्चे (काँटेदार) प्रक्रियाओं की स्मृति के उपयोग का सार की खोज किया था के माध्यम से पढ़ने के बाद। यह एक ग्राफ (ज्यादा बेहतर) की ओर जाता है इस प्रकार है:

Multiprocessing Workers with Include Children Flag

लेकिन क्या मैं तलाश कर रहा हूँ समय के साथ प्रत्येक व्यक्ति उपप्रक्रिया की स्मृति उपयोग इतना है कि मैं सभी कर्मचारियों (और मास्टर) प्लॉट कर सकते हैं है एक ही ग्राफ पर। मेरा विचार है कि प्रत्येक उपप्रोसेसर memory_usage एक अलग लॉग फ़ाइल में लिखा गया है, जिसे मैं कल्पना कर सकता हूं।

+0

यदि कोई दिलचस्पी है तो https://github.com/fabianp/memory_profiler/issues/118 पर गिटहब पर डेवलपर्स के साथ इस प्रश्न पर चर्चा की जा रही है। – bbengfort

उत्तर

1

आज तक, स्मृति प्रोफाइलर लाइब्रेरी में एक नई सुविधा जोड़ा गया है जो वास्तव में ऐसा करता है। आप इस कार्यक्षमता, पहले अद्यतन memory_profiler इस प्रकार की जरूरत है:

$ pip install -U memory_profiler 

यह स्मृति प्रोफाइलर की v0.44 रिलीज स्थापित करना चाहिए। आप तो -M झंडा देखना तुम जाना अच्छा कर रहे हैं, तो

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 

: कि यह देखने के लिए, रन कार्रवाई पर मदद के आदेश का उपयोग करें!

इसके बाद आप अपनी स्क्रिप्ट के रूप में निम्नानुसार चला सकते हैं:

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

और आप एक आंकड़ा है कि इस तरह दिखता है मिलना चाहिए:

mprof tracking individual child proccesses

ध्यान दें कि आप --include-children ध्वज के रूप में उपयोग करते हैं ठीक है, मुख्य प्रक्रिया मेमोरी सभी बच्चों और मुख्य का कुल स्मृति उपयोग होगा, जो एक उपयोगी साजिश भी है।

+0

ऐसा करने में सहायता के लिए @ fabian-pedregosa के लिए विशेष धन्यवाद! – bbengfort

+0

इस मोड में टाइमस्टैम्प और '@ प्रोफाइल' सजावट को सक्षम करने के बारे में कैसे? क्या यह संभव है? – petroslamb

+0

मुझे यकीन नहीं है कि टाइमस्टैम्प को सक्षम करने के बारे में आपका क्या मतलब है? मुझे लगता है कि यह '@ प्रोफ़ाइल' सजावट के साथ संभव होना चाहिए, यह एक ही तर्क का उपयोग करता है। – bbengfort

संबंधित मुद्दे