2012-01-06 23 views
7

मुझे खेद है कि यह कुछ लोगों के लिए बहुत आसान है, लेकिन मुझे अभी भी पाइथन के मल्टीप्रोसेसिंग के साथ चाल नहीं मिल रही है। मैंने
http://docs.python.org/dev/library/multiprocessing
http://pymotw.com/2/multiprocessing/basics.html और कई अन्य ट्यूटोरियल और उदाहरण जो Google मुझे देता है ... उनमें से कई भी यहां से हैं।समानांतर प्रक्रियाओं के लिए पायथन मल्टीप्रोसेसिंग

ठीक है, मेरी स्थिति यह है कि मुझे कई numpy matrices की गणना करना है और मुझे बाद में उन्हें एक एकल मैपिक्स में स्टोर करने की आवश्यकता है। मान लीजिए कि मैं 20 कोर का उपयोग करना चाहता हूं (या मैं 20 कोर का उपयोग कर सकता हूं) लेकिन मैंने पूल संसाधन का सफलतापूर्वक उपयोग नहीं किया है क्योंकि यह पूल "मरने" तक जीवित रहता है। इसलिए मैं कुछ इस तरह कर रही पर सोचा:

from multiprocessing import Process, Queue 
import numpy as np 

def f(q,i): 
    q.put(np.zeros((4,4))) 

if __name__ == '__main__': 
    q = Queue() 
    for i in range(30): 
      p = Process(target=f, args=(q,)) 
      p.start() 
      p.join() 
    result = q.get() 
    while q.empty() == False: 
      result += q.get() 
    print result 

लेकिन तब यह प्रक्रियाओं की तरह लग रहा समानांतर में नहीं चला लेकिन वे क्रमिक रूप से चलाने (कृपया मुझे ठीक कर लें मैं गलत हूँ) और मैं अगर पता नहीं है वे अपनी गणना करने के बाद मर जाते हैं (इसलिए 20 से अधिक प्रक्रियाओं के लिए जिन लोगों ने अपना हिस्सा किसी अन्य प्रक्रिया के लिए कोर मुक्त छोड़ दिया)। इसके अलावा, एक बहुत बड़ी संख्या के लिए (चलो 100.000 कहें), एक कतार में उन सभी मैट्रिक्स (जो वास्तव में भी बड़ा हो सकता है) को संग्रहीत करना बहुत मेमोरी का उपयोग करेगा, कोड को बेकार कर देगा क्योंकि विचार प्रत्येक पुनरावृत्ति पर हर परिणाम डालना है अंतिम परिणाम में, लॉक (और इसकी अधिग्रहण() और रिलीज() विधियों का उपयोग करने की तरह), लेकिन यदि यह कोड समांतर प्रसंस्करण के लिए नहीं है, तो लॉक भी बेकार है ...

मुझे उम्मीद है कि कोई मदद कर सकता है मुझे।

अग्रिम धन्यवाद!

उत्तर

14

आप सही हैं, वे आपके उदाहरण में अनुक्रमिक रूप से निष्पादित कर रहे हैं।

p.join() मौजूदा थ्रेड को निष्पादित होने तक अवरुद्ध करने का कारण बनता है। आप या तो अपने लूप के बाहर व्यक्तिगत रूप से अपनी प्रक्रियाओं में शामिल होना चाहते हैं (उदा।, उन्हें एक सूची में संग्रहीत करके और फिर इसे फिर से भरकर) या कॉलबैक के साथ numpy.Pool और apply_async जैसे कुछ का उपयोग करें। यह आपको वस्तुओं को चारों ओर रखने के बजाय सीधे अपने परिणामों में जोड़ने देगा।

उदाहरण के लिए:

def f(i): 
    return i*np.identity(4) 

if __name__ == '__main__': 
    p=Pool(5) 
    result = np.zeros((4,4)) 
    def adder(value): 
     global result 
     result += value 

    for i in range(30): 
     p.apply_async(f, args=(i,), callback=adder) 
    p.close() 
    p.join() 
    print result 

समापन और फिर अंत में पूल में शामिल होने सुनिश्चित करता है कि पूल की प्रक्रियाओं को पूरा कर लिया और result वस्तु गणना की जा रही समाप्त हो गया है। आप अपनी समस्या के समाधान के रूप में Pool.imap का उपयोग करके भी जांच कर सकते हैं। यही कारण है कि विशेष रूप से समाधान कुछ इस तरह दिखेगा:

if __name__ == '__main__': 
    p=Pool(5) 
    result = np.zeros((4,4)) 

    im = p.imap_unordered(f, range(30), chunksize=5) 

    for x in im: 
     result += x 

    print result 

यह अपने विशिष्ट स्थिति के लिए क्लीनर है, लेकिन जो कुछ भी करने के लिए आप अंततः करने के लिए कोशिश कर रहे हैं नहीं हो सकता।

अपनी विभिन्न परिणामों के सभी भंडारण के रूप में, अगर मैं अपने प्रश्न समझ में, तुम बस इसे बंद कर जोड़ सकते हैं कॉलबैक विधि में एक परिणाम में (ऊपर के रूप में) या आइटम-पर-एक-समय imap/imap_unordered का उपयोग कर (जो अभी भी परिणाम संग्रहीत करता है, लेकिन इसे इसे साफ़ कर देगा जैसा कि यह बनाता है)। फिर परिणाम में जोड़ने के लिए इसे लंबे समय तक संग्रहीत करने की आवश्यकता नहीं है।

+0

आपके उत्तर के लिए धन्यवाद! मैं पहले समाधान को और समझता हूं, और मुझे कॉलबैक बहुत उपयोगी लगता है क्योंकि imap_unordered सभी परिणामों को स्टोर करने लगता है, और यही वह है जो मैं स्मृति नहीं खाने के क्रम में करना चाहता हूं। पूल के लिए, मुझे यकीन नहीं है (जो मैंने maxtasksperchild विशेषता के बारे में पढ़ा है) कि अगर मेरे पास "x" प्रोसेसर हैं, तो "x" प्रक्रियाएं "x" पहली प्रक्रियाओं के मरने के बाद चलती हैं।मुझे यह भी यकीन नहीं है कि पहली "x" प्रक्रियाओं के लिए आवंटित स्मृति कॉलबैक के बाद निःशुल्क है या नहीं। मैं कई और बड़े मैट्रिस का उपयोग करते समय अपने पीसी को "ब्लॉक" न करने के क्रम में पूछता हूं – Carlos

+0

ओह! मुझे लगता है कि अब मैं इसे प्राप्त करता हूं: जब तक पूल जीवित रहता है तब तक मजदूर जीवित होते हैं, लेकिन जैसे ही वे एक प्रक्रिया पूरी करते हैं, वे संसाधनों को मुक्त करते हैं और फिर अगली प्रक्रिया लेते हैं और गणना करते हैं ... क्या यह है? – Carlos

+0

यूप, यह इसके बारे में है। मैं 'पूल' के बारे में ज्यादा चिंता नहीं करता हूं या एक विकल्प नहीं ढूंढता जब तक कि वास्तव में आपके पास प्रोफाइलिंग प्रोफाइल न हो, यह इंगित करता है कि यह एक समस्या है। अनुकूलन आप कर सकते हैं, लेकिन जब तक आप प्रदर्शन नहीं करते हैं कि आपके असली सिस्टम में कोई समस्या है, उनमें से अधिकतर परेशानी के लायक नहीं हैं। –

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