2015-07-09 11 views
7

मेरे पास 24 भौतिक कोर (कम से कम मुझे ऐसा बताया गया था) के साथ एक मशीन है डेबियन: Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.68-1+deb7u1 x86_64 GNU/Linux चल रहा है। यह सही हो रहा है:पायथन: मल्टीप्रोसेसिंग, 8/24 कोर लोड

[email protected]:~/$ cat /proc/cpuinfo | grep processor 
processor : 0 
processor : 1 
<...> 
processor : 22 
processor : 23 

मैं कुछ पायथन के multiprocessing.pool.Pool के साथ सभी कोर लोड करने की कोशिश मुद्दों था। मैंने Pool(processes=None) का उपयोग किया; दस्तावेज़ कहते हैं कि प्रदान किए जाने पर पायथन cpu_count() का उपयोग करता है।

अलास, केवल 8 कोर 100% लोड किए गए, अन्य निष्क्रिय बने रहे (मैंने CPU लोड की निगरानी के लिए htop का उपयोग किया)। मैंने सोचा था कि मैं Pools ठीक से खाना बनाना नहीं कर सकते हैं और 24 प्रक्रियाओं "मैन्युअल" को लागू करने की कोशिश की:

print 'Starting processes...' 
procs = list() 
for param_set in all_params: # 24 items 
    p = Process(target=_wrap_test, args=[param_set]) 
    p.start() 
    procs.append(p) 

print 'Now waiting for them.' 
for p in procs: 
    p.join() 

मैं प्रक्रियाओं मैंने शुरू से 24 "ग्रीटिंग" संदेश था:

Starting processes... 
Executing combination: Session len: 15, delta: 10, ratio: 0.1, eps_relabel: 0.5, min_pts_lof: 5, alpha: 0.01, reduce: 500 
< ... 22 more messages ... > 
Executing combination: Session len: 15, delta: 10, ratio: 0.1, eps_relabel: 0.5, min_pts_lof: 7, alpha: 0.01, reduce: 2000 
Now waiting for them. 

लेकिन अभी भी केवल 8 कोर लोड किया गया:

enter image description here

मैं तो वहाँ हूँ कि यहाँ पर पढ़ा है ए numpy, ओपनबीएलएस और मल्टीकोर निष्पादन के साथ समस्याएं हैं। इस तरह मैं अपने कोड शुरू है:

OPENBLAS_MAIN_FREE=1 python -m tests.my_module 

और सभी आयातों मैं करता हूँ के बाद:

os.system("taskset -p 0xff %d" % os.getpid()) 

तो, यहां सवाल यह है: मैं सभी कोर पर 100% लोड करने के लिए क्या करना चाहिए? क्या यह सिर्फ मेरा खराब पायथन उपयोग है या इसमें मल्टीकोर मशीनों पर ओएस सीमाओं के साथ कुछ करना है?

अद्यतन: एक और दिलचस्प बात htop आउटपुट के भीतर कुछ असंगतता है। यदि आप उपरोक्त छवि को देखते हैं, तो आप देखेंगे कि सीपीयू लोड बार के नीचे की तालिका 8 कोर से अधिक के लिए 30-50% भार दिखाती है, जो लोड बार कहने से निश्चित रूप से अलग है। फिर, top उन सलाखों से सहमत है: 8 कोर 100% -लोड, अन्य निष्क्रिय।

एक बार फिर से अद्यतन:

मैं पर this rather popular post इस्तेमाल किया तो जब मैं सभी आयातों के बाद os.system("taskset -p 0xff %d" % os.getpid()) लाइन गयी। मैं स्वीकार करने के लिए है कि मैं बहुत ज्यादा नहीं सोचा था कि जब मैंने किया था कि, विशेष रूप से इस पढ़ने के बाद है: इस लाइन मॉड्यूल आयात के बाद चिपकाया गया

, मेरे उदाहरण अब सभी कोर पर चलाता है

मैं एक साधारण आदमी हूँ। मैं देखता हूं "एक आकर्षण की तरह काम करता है", मैं कॉपी और पेस्ट करता हूं। वैसे भी, मेरे कोड के साथ खेलते समय मैं अंततः इस लाइन को हटा दिया। उसके बाद मेरे कोड ने "मैनुअल" Process प्रारंभिक परिदृश्य के लिए सभी 24 कोरों पर निष्पादन करना शुरू कर दिया। Pool परिदृश्य के लिए एक ही समस्या बनी रही, इससे कोई फर्क नहीं पड़ता कि एफ़िनिटी चाल का उपयोग किया गया था या नहीं।

मुझे नहीं लगता कि यह एक वास्तविक जवाब है 'क्योंकि मुझे नहीं पता कि यह समस्या Pool के साथ क्या है, लेकिन कम से कम मैं सभी कोर पूरी तरह से लोड हो गया। धन्यवाद!

+0

क्या आप वाकई 1 प्रोसेसर बोर्ड हैं? मैंने अफवाह सुना है कि पायथन मल्टीप्रोसेसिंग (1 सीपीयू से अधिक का उपयोग नहीं कर सकता) – deathangel908

+0

@ deathangel908 मुझे लगता है कि इसमें प्रत्येक 6 सीपीयू के साथ 4 सीपीयू है। लेकिन यह पहले से ही 6 कोर से अधिक का उपयोग करता है, इसलिए मुझे लगता है कि यह मुद्दा नहीं है। – oopcode

+0

@ deathangel908 जो गलत है: सभी मशीन संसाधनों का उपयोग करने के लिए थ्रेडिंग प्राप्त करने में समस्याएं हैं, लेकिन अलग यूनिक्स प्रक्रियाओं का उपयोग करके मल्टीप्रोसेसिंग, पायथन द्वारा सीमित नहीं है। मेरा अनुमान है कि कुछ कर्नेल सेटिंग है जो ओपी अनुमानित रूप से ठीक से सेट नहीं है। – msw

उत्तर

2

भले ही आप इस मुद्दे को हल करते हैं, मैं विचारों को स्पष्ट करने के लिए इसे समझाने की कोशिश करूंगा।

जो मैंने पढ़ा है, उसके लिए प्रदर्शन में सुधार करने के लिए numpy बहुत "जादू" करता है। जादू की चाल में से एक प्रक्रिया के सीपीयू संबंध स्थापित करना है।

सीपीयू एफ़िनिटी ओएस शेड्यूलर का अनुकूलन है। यह मूल रूप से एक ही सीपीयू कोर पर हमेशा चलने वाली प्रक्रिया को लागू करता है।

यह सीपीयू कैश को अमान्य करने और संदर्भ इलाके से लाभ बढ़ाने की मात्रा को कम करने में प्रदर्शन को बेहतर बनाता है। उच्च कम्प्यूटेशनल कार्यों पर ये कारक वास्तव में महत्वपूर्ण हैं।

मुझे नुकीले पसंद नहीं है यह तथ्य यह है कि यह सब कुछ स्पष्ट रूप से करता है। अक्सर परेशान डेवलपर्स।

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

os.system("taskset -p 0xff %d" % os.getpid()) कमांड ओएस को आपके मुद्दे को हल करने वाले सभी कोरों पर एफ़िनिटी सेट करने का निर्देश देता है।

यदि आप पूल पर काम करना चाहते हैं तो आप निम्न चाल कर सकते हैं।

import os 
from multiprocessing import Pool 


def set_affinity_on_worker(): 
    """When a new worker process is created, the affinity is set to all CPUs""" 
    print("I'm the process %d, setting affinity to all CPUs." % os.getpid()) 
    os.system("taskset -p 0xff %d" % os.getpid()) 


if __name__ == '__main__': 
    p = Pool(initializer=set_affinity_on_worker) 
    ... 
संबंधित मुद्दे