2009-03-19 24 views
50

मैं समझ सकता हूं कि कोई प्रोग्राम कैसे लिख सकता है जो एकाधिक प्रक्रियाओं या धागे का उपयोग करता है: कांटा() एक नई प्रक्रिया और आईपीसी का उपयोग करें, या एकाधिक धागे बनाएं और संचार तंत्र के उन प्रकारों का उपयोग करें।यह नियंत्रित करने के लिए कि कौन सी कोर एक प्रक्रिया चलती है?

मैं संदर्भ स्विचिंग को भी समझता हूं। यही है, केवल एक बार सीपीयू के साथ, ऑपरेटिंग सिस्टम प्रत्येक प्रक्रिया के लिए समय निर्धारित करता है (और वहां कई शेड्यूलिंग एल्गोरिदम हैं) और इस प्रकार हम एक साथ कई प्रक्रियाओं को चलाने के लिए प्राप्त करते हैं।

और अब हम मल्टी कोर प्रोसेसर (या मल्टी-प्रोसेसर कंप्यूटर) है, हम दो प्रक्रियाओं दो अलग-अलग कोर पर एक साथ चल सकते थे।

मेरा प्रश्न पिछले परिदृश्य के बारे में है: कर्नेल नियंत्रण जो कोर एक प्रक्रिया पर चलता है कैसे करता है? कौन सी सिस्टम कॉल (लिनक्स में, या यहां तक ​​कि विंडोज़) एक विशिष्ट कोर पर एक प्रक्रिया निर्धारित करता है?

कारण मैं पूछ रहा हूँ: मैं स्कूल है जहाँ हम कंप्यूटिंग में हाल ही में एक विषय का पता लगाने के लिए कर रहे हैं के लिए एक परियोजना पर काम कर रहा हूँ - और मैं मल्टी कोर आर्किटेक्चर चुना है। इस तरह के पर्यावरण में कार्यक्रम कैसे करें (डेडलॉक या रेस की स्थिति के लिए कैसे देखना है) पर बहुत सारी सामग्री प्रतीत होती है लेकिन अलग-अलग कोर को नियंत्रित करने पर ज्यादा कुछ नहीं। मुझे कुछ प्रदर्शन कार्यक्रम लिखने और कुछ असेंबली निर्देश या सी कोड को प्रस्तुत करने में सक्षम होना पसंद है "देखें, मैं दूसरे कोर पर एक अनंत लूप चला रहा हूं, के लिए CPU उपयोग में स्पाइक को देखें जो विशिष्ट कोर "।

कोई कोड उदाहरण? या ट्यूटोरियल?

संपादित करें: स्पष्टीकरण के लिए - कई लोगों ने कहा है कि इस ओएस का उद्देश्य है, और कहा कि एक ओएस इस का ख्याल रखना चाहिए। मैं पूरी तरह से सहमत! लेकिन फिर मैं जो पूछ रहा हूं (या महसूस करने की कोशिश कर रहा हूं) वह है जो ऑपरेटिंग सिस्टम वास्तव में ऐसा करता है। शेड्यूलिंग एल्गोरिदम नहीं, लेकिन अधिक "कोर को चुनने के बाद, कोर प्रारंभ निर्देशों को लाने के लिए कौन से निर्देश निष्पादित किए जाने चाहिए?"

+1

संभव यहाँ जवाब: http://stackoverflow.com/questions/980999/what-does-multicore-assembly-language-look-like, उत्तर में से एक स्टार्टअप इंटरप्रोसेसर इंटरप्ट का वर्णन करता है, जिसे एक सीपीयू कोर से चिपसेट एपीआईसी में भेजा जा रहा है, और इसका उपयोग दूसरे सीपीयू को शुरू करने और उस पर कोड चलाने के लिए किया जा सकता है सीपीयू एक विशिष्ट पते पर –

+0

हमारे स्वयं के ओएस में एसएमपी शुरू करने का न्यूनतम उदाहरण: http://stackoverflow.com/a/33651438/895245 उस के साथ बजाना + स्मृति को सिंक्रनाइज़ करना तरीका होना चाहिए। –

उत्तर

31

जैसा कि अन्य ने उल्लेख किया है, प्रोसेसर एफ़िनिटी ऑपरेटिंग सिस्टम विशिष्ट है। यदि आप ऑपरेटिंग सिस्टम की सीमाओं के बाहर ऐसा करना चाहते हैं, तो आप बहुत मज़ेदार हैं, और इसके द्वारा मेरा मतलब दर्द है।

उस ने कहा, दूसरों ने Win32 के लिए SetProcessAffinityMask का उल्लेख किया है। प्रोसेसर एफ़िनिटी सेट करने के लिए किसी ने भी लिनक्स कर्नेल मार्ग का उल्लेख नहीं किया है, और इसलिए मैं करूँगा। आपको sched_set_affinity फ़ंक्शन का उपयोग करने की आवश्यकता है। कैसे a nice tutorial पर है।

+1

मैंने कुछ समय पहले इस विषय पर एक लेख लिखा था, लेकिन यह स्लोवाक में लिखा गया है, इसलिए मुझे लगता है कि उस व्यक्ति की मदद नहीं करेगा :) वैसे भी, आपका जवाब सही दिशा में जाता है, इसलिए मैं आपको वोट दे रहा हूं अप :-) –

+0

यह ट्यूटोरियल "बनाया_thread" में एफ़िनिटी मास्क सेट करता है, जो, AFAICT, वर्तमान में चल रहा है जिस पर cpu को सख्ती से नहीं बोल रहा है। यह सिर्फ एक पूर्णांक है जो बिटमैस्क में अनुक्रमणित करने के लिए इस तरह से बढ़ता है और उपयोग किया जाता है, लेकिन ऐसा लगता है कि वर्तमान में कौन सा प्रोसेसर उपयोग में नहीं है, इसका वास्तविक निर्धारण नहीं है, केवल बाल प्रक्रियाओं को चलाने के लिए सीमित है cpu # जो उस क्रम से मेल खाता है जिसमें बाल प्रक्रियाएं बनाई जाती हैं। – Jotorious

1

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

उदाहरण के लिए, यदि आपने कोर एक्स पर शुरू करने की प्रक्रिया को बताया है, लेकिन कोर एक्स पहले से ही भारी भार के तहत था, तो आप ओएस को इसे संभालने के बजाए इससे भी बदतर हो जाएंगे।

+0

हां, मैंने ऊपर उठाया है, लेकिन शायद आपके पास प्रक्रिया चल रही है और आप किसी भी कोर पर बी, सी, और डी को प्रक्रिया शुरू करना चाहते हैं, जो एक चल रहा है ए को छोड़कर पूरी तरह से उचित लगता है। –

30
आम तौर पर

निर्णय जो कोर के बारे में एक ऐप्लिकेशन पर चलेंगे प्रणाली द्वारा किया जाता है। हालांकि, आप किसी कोर के लिए "एफ़िनिटी" सेट कर सकते हैं ताकि ओएस को उस कोर पर केवल ऐप चलाने के लिए कहा जा सके। आम तौर पर यह एक अच्छा विचार नहीं है, लेकिन कुछ दुर्लभ मामले हैं जहां यह समझ में आ सकता है।

खिड़कियां, उपयोग कार्य प्रबंधक में ऐसा करने के लिए सही प्रक्रिया पर क्लिक करें और "सेट समानता" चुनें। आप इसे सेटट्रेड एफ़िनिटीमास्क, सेटप्रोसेसएफिनिटीमास्क या सेट थ्रेड इडिलप्रोसेसर जैसे कार्यों का उपयोग करके विंडोज में प्रोग्रामेटिक रूप से कर सकते हैं।

ईटीए:

आप कैसे ओएस वास्तव में समय-निर्धारण, ये लिंक की जाँच करने के लिए चाहते हो सकता है है में रुचि रखते हैं:

Wikipedia article on context switching

Wikipedia article on scheduling

Scheduling in the linux kernel

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

संदर्भ स्विच कैसे होता है इसका कार्यान्वयन विवरण CPU & ओएस निर्भर है। इसमें आम तौर पर कर्नेल मोड में स्विच शामिल होता है, ओएस पिछले धागे की स्थिति को सहेजता है, नए थ्रेड की स्थिति लोड करता है, फिर उपयोगकर्ता मोड पर वापस स्विच करता है और नए लोड किए गए थ्रेड को फिर से शुरू करता है। ऊपर से जुड़े संदर्भ स्विचिंग आलेख में इसके बारे में कुछ और जानकारी है।

+0

+1 इसे करने का आसान तरीका प्रदान करने के लिए +1। –

+0

ध्यान दें कि एफ़िनिटी मास्क को बाल प्रक्रियाओं द्वारा विरासत में मिला है, इसलिए यदि आप इसे एक्सप्लोरर पर सेट करते हैं, तो सभी लॉन्च किए गए एप्लिकेशन भी उपलब्ध प्रोसेसर के सबसेट का उपयोग करेंगे। – Richard

1

मुझे असेंबली निर्देश नहीं पता हैं। लेकिन विंडोज एपीआई फ़ंक्शन SetProcessAffinityMask है। आप कुछ समय पहले पिकासा को चलाने के लिए an example देख सकते हैं, जिसे केवल एक कोर

2

जैसा कि अन्य लोगों ने उल्लेख किया है, यह ऑपरेटिंग सिस्टम द्वारा नियंत्रित है। ओएस के आधार पर, यह आपको सिस्टम कॉल प्रदान नहीं कर सकता है जो आपको प्रभावित करने की अनुमति देता है कि किसी दिए गए प्रक्रिया को किस कोर पर निष्पादित किया जाता है। हालांकि, आपको आमतौर पर ओएस को डिफ़ॉल्ट व्यवहार करने देना चाहिए। यदि आपके पास 37 प्रक्रियाओं के साथ 4-कोर सिस्टम है, और उनमें से 34 प्रक्रियाएं सो रही हैं, तो यह शेष 3 सक्रिय प्रक्रियाओं को अलग-अलग कोर पर शेड्यूल करने जा रही है।

आप शायद बहुत ही विशिष्ट बहुप्रचारित अनुप्रयोगों में कोर affinities के साथ खेलने पर एक गति बढ़ावा देखेंगे। उदाहरण के लिए, मान लें कि आपके पास 2 ड्यूल-कोर प्रोसेसर वाला सिस्टम है। मान लीजिए कि आपके पास 3 धागे के साथ एक एप्लीकेशन है, और दो थ्रेड डेटा के उसी सेट पर भारी रूप से काम करते हैं, जबकि तीसरा धागा डेटा के एक अलग सेट का उपयोग करता है। इस मामले में, आप दो प्रोसेसर पर एक ही प्रोसेसर पर बातचीत करते हैं और दूसरे प्रोसेसर पर तीसरे धागे को लेकर सबसे अधिक लाभ उठाएंगे, तब से वे एक कैश साझा कर सकते हैं। ओएस को पता नहीं है कि प्रत्येक थ्रेड को किस स्मृति को एक्सेस करने की आवश्यकता है, इसलिए यह उचित रूप से कोर को थ्रेड आवंटित नहीं कर सकता है।

यदि आप में रुचि रखते हैं तो ऑपरेटिंग सिस्टम, scheduling पर पढ़ें। X86 पर मल्टीप्रोसेसिंग का नट किरकिरा विवरण Intel 64 and IA-32 Architectures Software Developer's Manuals में पाया जा सकता है। वॉल्यूम 3 ए, अध्याय 7 और 8 में प्रासंगिक जानकारी है, लेकिन ध्यान रखें कि इन मैनुअल बेहद तकनीकी हैं।

3

OpenMPI परियोजना एक library to set the processor affinityपर लिनक्स में एक पोर्टेबल तरीका है।

कुछ समय पहले, मैंने इसे एक प्रोजेक्ट में उपयोग किया है और यह ठीक काम करता है।

चेतावनी: मुझे याद है कि ऑपरेटिंग सिस्टम कोर को कैसे दिखाता है, यह जानने में कुछ समस्याएं थीं। मैंने इसे 2 ज़ीऑन सीपीयू सिस्टम में 4 कोर के साथ इस्तेमाल किया।

cat /proc/cpuinfo पर एक नज़र मदद कर सकता है। मेरे द्वारा उपयोग किए जाने वाले बॉक्स पर, यह बहुत अजीब है। उबला हुआ उत्पादन अंत में है।

जाहिर है, समान संख्या में कोर पहले सीपीयू पर हैं और अजीब संख्या वाले कोर दूसरे सीपीयू पर हैं। हालांकि, अगर मुझे सही याद है, तो कैश के साथ कोई समस्या थी। इन इंटेल ज़ीऑन प्रोसेसर पर, प्रत्येक सीपीयू पर दो कोर अपने एल 2 कैश साझा करते हैं (मुझे याद नहीं है कि प्रोसेसर में एल 3 कैश है या नहीं)। मुझे लगता है कि वर्चुअल प्रोसेसर 0 और 2 ने एक एल 2 कैश साझा किया, 1 और 3 साझा किया गया एक, 4 और 6 साझा किया गया एक और 5 और 7 साझा किया गया।

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

processor  : 0 
physical id  : 0 
siblings  : 4 
core id   : 0 
cpu cores  : 4 

processor  : 1 
physical id  : 1 
siblings  : 4 
core id   : 0 
cpu cores  : 4 

processor  : 2 
physical id  : 0 
siblings  : 4 
core id   : 1 
cpu cores  : 4 

processor  : 3 
physical id  : 1 
siblings  : 4 
core id   : 1 
cpu cores  : 4 

processor  : 4 
physical id  : 0 
siblings  : 4 
core id   : 2 
cpu cores  : 4 

processor  : 5 
physical id  : 1 
siblings  : 4 
core id   : 2 
cpu cores  : 4 

processor  : 6 
physical id  : 0 
siblings  : 4 
core id   : 3 
cpu cores  : 4 

processor  : 7 
physical id  : 1 
siblings  : 4 
core id   : 3 
cpu cores  : 4 
+0

इसके अलावा एसएलईआरटी इसका प्रयास करता है और प्रोसेसर या प्रोसेसर समूह का चयन करने के लिए बहुत परिष्कृत तंत्र है। –

5

कुछ भी नहीं कहता है "अब इस प्रक्रिया को चलाने शुरू करें"।

कोर प्रक्रिया नहीं देखता है, यह केवल निष्पादन योग्य कोड और विभिन्न चलने वाले स्तरों और संबंधित सीमाओं के बारे में जानता है जिन्हें निष्पादित किया जा सकता है।

जब कंप्यूटर बूट करता है, सादगी के लिए केवल एक कोर/प्रोसेसर सक्रिय होता है और वास्तव में कोई कोड चलाता है। फिर यदि ओएस मल्टीप्रोसेसर सक्षम है, तो यह कुछ कोर विशिष्ट निर्देशों के साथ अन्य कोर को सक्रिय करता है, अन्य कोर संभवतः उसी कोर से दूसरे स्थान के रूप में उठाए जाते हैं और वहां से चलते हैं।

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

तकनीकी रूप से कुछ भी नहीं है जो कोर को एक ही समय में सटीक उसी कोड को चलाने से रोकता है (और कई अनलॉक फ़ंक्शंस), लेकिन जब तक कोड की अपेक्षा करने के लिए लिखा नहीं जाता है, तो यह संभवतः अपने आप को पेश करेगा।

परिदृश्य अधिक विदेशी मेमोरी मॉडल (ऊपर "सामान्य" रैखिक एकल काम करने वाली मेमोरी स्पेस मानता है) के साथ वीरडर जाता है जहां कोर सभी आवश्यक स्मृति नहीं देखते हैं और अन्य कोर के पट्टियों से कोड लाने पर आवश्यकताएं हो सकती हैं, लेकिन यह बहुत अधिक है बस कोर को पिन किए गए कार्य को आसानी से संभाला जाता है (एसपीयू के साथ AFAIK सोनी पीएस 3 आर्किटेक्चर ऐसा ही है)।

1

प्रोसेसर की संख्या पता लगाने के लिए के बजाय का उपयोग कर/proc/cpuinfo बस चलाने:

nproc 

विशिष्ट प्रोसेसर के एक समूह पर एक प्रक्रिया चलाने के लिए:

taskset --cpu-list 1,2 my_command 

कहेंगे कि मेरी कमांड केवल सीपीयू 1 या 2 पर चल सकता है।

4 प्रोसेसर पर 4 प्रोग्राम करने पर प्रोग्राम चलाने के लिए पैरामीटरकरण का उपयोग करें। कार्यक्रम के लिए तर्क यह कुछ अलग करना बताता है: एक सरणी में

for i in `seq 0 1 3`; 
do 
    taskset --cpu-list $i my_command $i; 
done 

इस का एक अच्छा उदाहरण 8 लाख आपरेशन के साथ काम कर रहा है ताकि 0 (2mil -1) प्रोसेसर 1 के लिए चला जाता है, के लिए 2mil (4 मिली -1) प्रोसेसर 2 और इतने पर।

आप का उपयोग htop स्थापित करके apt-get/यम और कमांड लाइन पर चल रहे प्रत्येक प्रक्रिया पर लोड देख सकते हैं:

htop