2010-12-26 14 views
6

का उपयोग करके विशाल शब्दकोश साझा करना मैं मल्टीप्रोसेसिंग का उपयोग करके, शब्दकोश में संग्रहीत बहुत बड़ी मात्रा में डेटा संसाधित कर रहा हूं। असल में मैं जो कुछ कर रहा हूं वह कुछ हस्ताक्षर लोड कर रहा है, जो एक शब्दकोश में संग्रहीत है, इसमें से एक साझा dict ऑब्जेक्ट का निर्माण कर रहा है (प्रबंधक.dict() द्वारा लौटाई गई 'प्रॉक्सी' ऑब्जेक्ट प्राप्त करना) और इस प्रॉक्सी को उस फ़ंक्शन के तर्क के रूप में पास करना मल्टीप्रोसेसिंग में निष्पादित किया जाएगा।पायथन: मल्टीप्रोसेसिंग

बस स्पष्ट करने के लिए:

signatures = dict() 
load_signatures(signatures) 
[...] 
manager = Manager() 
signaturesProxy = manager.dict(signatures) 
[...] 
result = pool.map (myfunction , [ signaturesProxy ]*NUM_CORES) 

अब, सब कुछ पूरी तरह से काम करता है अगर हस्ताक्षर 2 लाख से भी कम समय प्रविष्टियों या तो है। वैसे भी, मुझे 5.8 एम कुंजी के साथ एक शब्दकोश को संसाधित करना है (हस्ताक्षर बाइनरी प्रारूप में 4.8 जीबी फ़ाइल उत्पन्न करता है)।

Traceback (most recent call last): 
    File "matrix.py", line 617, in <module> 
signaturesProxy = manager.dict(signatures) 
    File "/usr/lib/python2.6/multiprocessing/managers.py", line 634, in temp 
token, exp = self._create(typeid, *args, **kwds) 
    File "/usr/lib/python2.6/multiprocessing/managers.py", line 534, in _create 
id, exposed = dispatch(conn, None, 'create', (typeid,)+args, kwds) 
    File "/usr/lib/python2.6/multiprocessing/managers.py", line 79, in dispatch 
raise convert_to_error(kind, result) 
multiprocessing.managers.RemoteError: 
--------------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/usr/lib/python2.6/multiprocessing/managers.py", line 173, in handle_request 
    request = c.recv() 
EOFError 
--------------------------------------------------------------------------- 

मैं जानता हूँ कि डेटा संरचना बहुत बड़ा है, लेकिन मैं एक मशीन पर काम कर रहा हूँ w/32GB रैम सुसज्जित है, और शीर्ष चल रहा है कि देखें: इस मामले में, प्रक्रिया प्रॉक्सी वस्तु के निर्माण के दौरान मर जाता है हस्ताक्षर लोड करने के बाद, प्रक्रिया 7 जीबी रैम पर है। इसके बाद यह प्रॉक्सी ऑब्जेक्ट का निर्माण शुरू करता है और रैम का उपयोग ~ 17 जीबी रैम तक जाता है लेकिन 32 के करीब कभी नहीं मिलता है। इस बिंदु पर, राम उपयोग जल्दी से कम हो जाता है और प्रक्रिया उपर्युक्त त्रुटि से समाप्त हो जाती है। तो मुझे लगता है कि यह आउट-ऑफ-मेमोरी त्रुटि के कारण नहीं है ...

कोई विचार या सुझाव?

, धन्यवाद

डेविड

उत्तर

-3

यदि शब्दकोश केवल पढ़ने के लिए हैं, तो आपको अधिकांश ऑपरेटिंग सिस्टम में प्रॉक्सी ऑब्जेक्ट्स की आवश्यकता नहीं है।

श्रमिकों को शुरू करने से पहले बस शब्दकोश लोड करें, और उन्हें कहीं भी रखें, वे पहुंच योग्य होंगे; सबसे सरल स्थान एक मॉड्यूल के लिए वैश्विक स्तर पर है। वे श्रमिकों से पठनीय होंगे।

from multiprocessing import Pool 

buf = "" 

def f(x): 
    buf.find("x") 
    return 0 

if __name__ == '__main__': 
    buf = "a" * 1024 * 1024 * 1024 
    pool = Pool(processes=1) 
    result = pool.apply_async(f, [10]) 
    print result.get(timeout=5) 

यह केवल प्रत्येक प्रक्रिया के लिए स्मृति के 1GB संयुक्त, नहीं 1GB उपयोग करता है, क्योंकि किसी भी आधुनिक ओएस कांटा से पहले बनाए गए डेटा की एक प्रतिलिपि-ऑन-राइट छाया कर देगा। बस याद रखें कि डेटा में किए गए परिवर्तन अन्य श्रमिकों द्वारा नहीं देखे जाएंगे, और निश्चित रूप से, आपके द्वारा बदले गए किसी भी डेटा के लिए स्मृति आवंटित की जाएगी।

यह कुछ स्मृति का उपयोग करेगा: संदर्भ गणना वाले प्रत्येक ऑब्जेक्ट का पृष्ठ संशोधित किया जाएगा, इसलिए इसे आवंटित किया जाएगा। क्या यह मामला डेटा पर निर्भर करता है।

यह किसी भी ओएस पर काम करेगा जो साधारण फोर्किंग लागू करता है। यह विंडोज पर काम नहीं करेगा; इसके (अपंग) प्रक्रिया मॉडल को प्रत्येक कार्यकर्ता के लिए पूरी प्रक्रिया को फिर से लॉन्च करने की आवश्यकता होती है, इसलिए डेटा साझा करने में यह बहुत अच्छा नहीं है।

+1

क्या यह विंडोज 7 के साथ काम करता है (जो निश्चित रूप से एक आधुनिक ओएस है?) –

+0

@ सेन: मुझे नहीं पता; इसका परीक्षण करने का प्रयास करें। मुझे संदेह है कि इसकी प्रक्रिया मॉडल पिछले संस्करणों की तुलना में अधिक आधुनिक है; विंडोज हमेशा इसके बारे में अंधेरे युग में रहा है। –

+1

(यादृच्छिक, गलत डाउनवॉट्स के लिए SO की तरह कुछ नहीं।) –

2

समय बचता है और सिस्टम स्तर के मुद्दों डिबग करने के लिए नहीं होने के हित में, हो सकता है आप 2 लाख ~ के तीन सेट में अपने 5.8 लाख रिकॉर्ड शब्दकोश विभाजित किया जा सकता प्रत्येक, और नौकरी 3 बार चलाते हैं।

+0

मैं कर सकता है, लेकिन यह, के रूप में सर्वोत्कृष्ट समाधान नहीं है वैसे भी, अंत में मैं पूरी शब्दकोश को फिर से संगठित और अन्य कार्यों के लिए उपयोग करना होगा –

+0

तो यह लग रहा है अपने कार्य की तरह Hadoop के लिए उपयुक्त होगा/MapReduce ... शायद आपको इसे देखना चाहिए। – Fragsworth

6

आप डेटाबेस के साथ ऐसा क्यों नहीं करते? डेटाबेस एड्रेसेबल/भौतिक रैम तक सीमित नहीं हैं और मल्टीथ्रेड/प्रक्रिया उपयोग के लिए सुरक्षित हैं।

0

मुझे लगता है कि आप जिस समस्या का सामना कर रहे थे वह था कि यह बढ़ने के साथ ही आकार या हैश तालिका का आकार बदल रहा था। प्रारंभ में, ताना में उपलब्ध बाल्टी की एक निश्चित संख्या है। मुझे पाइथन के बारे में निश्चित नहीं है, लेकिन मुझे पता है कि पर्ल 8 से शुरू होता है और फिर जब बाल्टी भर जाती है, तो हैश को 8 और (यानी) द्वारा बनाया जाता है।8, 16, 32, ...)।

बाल्टी हैश एल्गोरिदम के लिए एक लैंडिंग स्थान है। 8 स्लॉट का मतलब 8 प्रविष्टियों का नहीं है, इसका मतलब है 8 स्मृति स्थान। जब नया आइटम जोड़ा जाता है, तो उस कुंजी के लिए हैश उत्पन्न होता है, फिर उसे उस बाल्टी में संग्रहीत किया जाता है।

यह वह जगह है जहां टक्कर खेलती है। एक बाल्टी में जितनी अधिक चीजें हैं, धीमे कार्य को प्राप्त किया जाएगा, क्योंकि स्लॉट के गतिशील आकार के कारण वस्तुओं को अनुक्रमिक रूप से जोड़ा जाता है।

एक समस्या जो हो सकती है वह है कि आपकी चाबियाँ बहुत समान हैं और उसी हैश परिणाम का उत्पादन - जिसका अर्थ है कि अधिकांश कुंजी एक स्लॉट में हैं। हैश बाल्टी को पूर्व-आवंटित करने से इसे खत्म करने में मदद मिलेगी और वास्तव में प्रसंस्करण समय और कुंजी प्रबंधन में सुधार होगा, साथ ही इसे अब भी स्वैपिंग करने की आवश्यकता नहीं है।

हालांकि, मुझे लगता है कि आप अभी भी नि: शुल्क संगत स्मृति की मात्रा तक ही सीमित हैं और अंततः डेटाबेस समाधान पर जाने की आवश्यकता होगी।

साइड नोट: मैं अभी भी पाइथन के लिए नया हूं, मुझे पर्ल में पता है कि आप प्रिंट% HASHNAME कर हैश आंकड़े देख सकते हैं, यह बाल्टी उपयोग का वितरण दिखाएगा। टकराव की गणना की पहचान करने में आपकी सहायता करता है - आपको बाल्टी को पूर्व-आवंटित करने की आवश्यकता होती है। क्या यह पाइथन में भी किया जा सकता है?

रिच