2013-06-11 8 views
20

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

एप्लिकेशन डेटा के सेट पर विकासवादी एल्गोरिदम करता है। अधिकांश संचालन मूल्यांकन के अपवाद के साथ क्रमशः किया जाता है। सभी विकासवादी ऑपरेटरों को लागू करने के बाद सभी व्यक्तियों को नए फिटनेस मूल्य प्राप्त करने की आवश्यकता होती है, जो मूल्यांकन के दौरान किया जाता है। असल में यह केवल एक गणितीय गणना है जो फ्लोट्स (पायथन वाले) की सूची में किया जाता है। मूल्यांकन से पहले एक डेटा सेट एमपीआई के स्कैटर या पायथन के पूल.मैप द्वारा बिखरा हुआ है, फिर समांतर मूल्यांकन आता है और बाद में डेटा एमपीआई के इकट्ठा या फिर पूल.मैप तंत्र के माध्यम से वापस आता है।

मेरा बेंचमार्क प्लेटफार्म एक वर्चुअल मशीन (वर्चुअलबॉक्स) है जो कोर i7 (4/8 कोर), 8 जीबी रैम और एक एसएसडी ड्राइव पर ओपन एमपीआई 1.4.3 के साथ उबंटू 11.10 चला रहा है।

मुझे वास्तव में आश्चर्य की बात यह है कि मैं एक अच्छी गति प्राप्त करता हूं, हालांकि प्रक्रियाओं के एक निश्चित सीमा के बाद, एक संचार उपकरण के आधार पर, प्रदर्शन खराब हो जाता है। इसे नीचे दी गई तस्वीरों से सचित्र किया जा सकता है।

y अक्ष - प्रसंस्करण समय
एक्स अक्ष - (तैरता की एन.आर.) प्रत्येक व्यक्ति के आकार

1) बहु मॉड्यूल का उपयोग करना - - प्रक्रियाओं की एन.आर.
रंग Pool.map
enter image description here

2) एमपीआई का उपयोग करना - स्कैटर/इकट्ठा enter image description here

3) एक दूसरे को enter image description here

के शीर्ष पर दोनों चित्रों पहले मैं सोच रहा था कि यह हाइपरथ्रेडिंग की गलती है, क्योंकि बड़े डेटा सेट के लिए यह 4 प्रक्रियाओं (4 शारीरिक कोर) तक पहुंचने के बाद धीमी हो जाता है पर। हालांकि यह मल्टीप्रोसेसिंग मामले में भी दिखाना चाहिए और यह नहीं है। मेरा एक और अनुमान यह है कि एमपीआई संचार विधियां पाइथन की तुलना में बहुत कम प्रभावी हैं, हालांकि मुझे विश्वास करना मुश्किल लगता है।

क्या किसी के पास इन परिणामों के लिए कोई स्पष्टीकरण है?

जोड़ा:

मुझे विश्वास है कि यह सब के बाद Hyperthreading गलती है शुरू कर रहा हूँ। मैंने कोर i5 (2/4 कोर) वाली मशीन पर अपने कोड का परीक्षण किया और प्रदर्शन 3 या अधिक प्रक्रियाओं के साथ खराब है। मेरे दिमाग में आने वाला एकमात्र स्पष्टीकरण यह है कि i7 जिसका उपयोग मैं कर रहा हूं उसके पास हाइपरथ्रेडिंग के साथ समवर्ती रूप से मूल्यांकन की गणना करने के लिए पर्याप्त संसाधन (कैश?) नहीं हैं और 4 भौतिक कोरों पर चलाने के लिए 4 से अधिक प्रक्रियाओं को शेड्यूल करने की आवश्यकता है।

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

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

Pool.map:

def eval_population(func, pop): 
    for ind in pop: 
     ind.fitness.values = func(ind) 

    return pop 

# ... 
self.pool = Pool(8) 
# ... 

for iter_ in xrange(nr_of_generations): 
    # ... 
    self.pool.map(evaluate, pop) # evaluate is really an eval_population alias with a certain function assigned to its first argument. 
    # ... 

एमपीआई - स्कैटर/इकट्ठा

def divide_list(lst, n): 
    return [lst[i::n] for i in xrange(n)] 

def chain_list(lst): 
    return list(chain.from_iterable(lst)) 

def evaluate_individuals_in_groups(func, rank, individuals): 
    comm = MPI.COMM_WORLD 
    size = MPI.COMM_WORLD.Get_size() 

    packages = None 
    if not rank: 
     packages = divide_list(individuals, size) 

    ind_for_eval = comm.scatter(packages) 
    eval_population(func, ind_for_eval) 

    pop_with_fit = comm.gather(ind_for_eval) 

    if not rank: 
     pop_with_fit = chain_list(pop_with_fit) 
     for index, elem in enumerate(pop_with_fit): 
      individuals[index] = elem 

for iter_ in xrange(nr_of_generations): 
     # ... 
     evaluate_individuals_in_groups(self.func, self.rank, pop) 
     # ... 

जोड़ा 2: कि मैंने पहले बताया मैं अपने i5 मशीन पर कुछ परीक्षण किए गए के रूप में (2/4 कोर) और यहां परिणाम है: enter image description here

मैं भी 2 Xeons (2x 6/12 कोर) के साथ एक मशीन मिल गया है और बेंचमार्क दोहराया: enter image description here

अब मैं एक ही व्यवहार के 3 उदाहरण है। जब मैं भौतिक कोर की तुलना में अधिक प्रक्रियाओं में अपनी गणना चलाता हूं तो यह और भी खराब हो जाता है। मेरा मानना ​​है कि ऐसा इसलिए है क्योंकि संसाधनों की कमी के कारण एक ही भौतिक कोर की प्रक्रियाओं को समवर्ती रूप से निष्पादित नहीं किया जा सकता है।

+1

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

+0

मैं ओपन एमपीआई का उपयोग करता हूं, प्रश्न में जोड़ा गया। – Michal

+0

यदि आप अधिक संदर्भ प्रदान कर सकते हैं तो यह बहुत अच्छा होगा, उदाहरण के लिए कोड के उन हिस्सों को दिखाएं जहां डेटा वितरित किया जा रहा है (दोनों कार्यान्वयन)। आम तौर पर स्कैटर और ओपन एमपीआई स्केल में प्रक्रियाओं की संख्या के साथ बहुत अच्छी तरह से इकट्ठा होते हैं जब वे सभी एक नोड पर चल रहे होते हैं। –

उत्तर

5

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

mpi4py प्रत्येक संदेश के लिए एक प्रति बनाता है, क्योंकि यह वितरित स्मृति उपयोग पर लक्षित है। यदि आपका ओपनएमपीआई इंट्रा नोड संचार के लिए साझा स्मृति का उपयोग करने के लिए कॉन्फ़िगर नहीं किया गया है, तो यह संदेश कर्नेल के टीसीपी स्टैक को वापस और अन्य प्रक्रिया में वितरित करने के लिए भेजा जाएगा, जो फिर से कुछ ओवरहेड जोड़ देगा।

यदि आप केवल उसी मशीन के भीतर कंप्यूटेशंस करना चाहते हैं, तो यहां mpi का उपयोग करने की आवश्यकता नहीं है।

इनमें से कुछ पर चर्चा की in this thread.

अद्यतन ipc-benchmark परियोजना के कैसे विभिन्न संचार प्रकार विभिन्न प्रणालियों पर प्रदर्शन बाहर कुछ समझ बनाने की कोशिश करता है है। (मल्टीकोर, मल्टीप्रोसेसर, साझा स्मृति) और विशेष रूप से यह वर्चुअलाइज्ड मशीनों को कैसे प्रभावित करता है!

मैं आभासी मशीन पर आईपीसी-बेंचमार्क चलाने की सिफारिश करता हूं, और परिणाम पोस्ट करता हूं। यदि वे this बेंचमार्क जैसे कुछ भी देखते हैं तो यह आपको टीसीपी, सॉकेट और पाइप के बीच अंतर में एक बड़ी अंतर्दृष्टि ला सकता है।

+0

रहता है, मैं विभिन्न कंप्यूटिंग वातावरण में विकासवादी एल्गोरिदम का परीक्षण करने के लिए एक आवेदन पर काम कर रहा हूं: पीसी, क्लस्टर, ग्रिड इत्यादि ... मैं बहस नहीं कर रहा हूं कि यहां एमपीआई का उपयोग करने के लिए उचित है या नहीं। मैं सिर्फ उत्सुक हूं जहां ओवरहेड आते हैं। और जिस तरह से पाइथन पूल.मैप संचार के लिए एक कतार का उपयोग करता है, जिसे या तो पाइप या सॉकेट के साथ लागू किया जाता है। मैंने इसे सॉकेट का उपयोग करने के लिए कॉन्फ़िगर किया है, इसलिए संचार विधि समान है। – Michal

+0

@ मिचल ऐसा इसलिए नहीं है क्योंकि आप उन सॉकेट का उपयोग कर रहे हैं जिन्हें आप टीसीपी का उपयोग कर रहे हैं। यहां पाइप, सॉकेट या श्मिट, + बेंचमार्किंग टूल का उपयोग करने वाली विभिन्न गतियों पर कुछ रोचक स्लाइडें दी गई हैं जो आपको बताएंगी कि आपके सिस्टम पर सबसे तेज़ क्या हो सकता है (इस पर निर्भर करता है कि आपके कोर कैसे संवाद कर सकते हैं, आपके सीपीयू सॉकेट कैसे कर सकते हैं संवाद, और उनके numa डोमेन।) http://anil.recoil.org/talks/fosdem-io-2012.pdf –

+0

इसे इंगित करने के लिए धन्यवाद। मैं आपके द्वारा लिखे गए और आपके द्वारा दी गई वेबसाइट की जांच करेगा जब मेरे पास कुछ समय होगा। – Michal

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