कई कोर का उपयोग करके जी ++ के साथ संकलन


174

त्वरित प्रश्न: बड़ी परियोजनाओं को त्वरित रूप से संकलित करने के लिए (मल्टी मल्टी-सीपीयू के लिए एक समय में 4 स्रोत फ़ाइलों के लिए) संकलित करने के लिए जी ++ को स्वयं के कई उदाहरणों को अनुमति देने के लिए संकलक ध्वज क्या है?


क्या यह वास्तव में मदद करेगा? मेरे सभी संकलित कार्य सीपीयू बाउंड के बजाय I / O बाध्य हैं।
ब्रायन नोब्लुच

5
यहां तक ​​कि अगर वे I / O बाध्य हैं, तो आप संभवतः I / O लोड को अधिक रख सकते हैं जब CPU भारी बिट्स हो रहा हो (सिर्फ एक g ++ उदाहरण में लुल्ल होगा) और संभवतः I / O क्षमता प्राप्त करें यदि अनुसूचक के बारे में अधिक विकल्प हैं आगे डिस्क से क्या पढ़ना है। मेरा अनुभव रहा है कि make -jलगभग सदैव विवेकपूर्ण प्रयोग से कुछ सुधार होता है।
फ्लेक्सो

1
@BrianKnoblauch लेकिन मेरी मशीन पर (वास्तविक एक या वर्चुअलबॉक्स में), यह सीपीयू बाध्य है, मैंने पाया कि सीपीयू संकलन करते समय 'शीर्ष' कमांड के माध्यम से व्यस्त है।

1
भले ही वे I / O बाध्य हों, हम दर्द को कम करने के लिए gcc के ध्वज '-पाइप' का उपयोग कर सकते हैं।
大 大

बस इसे Google में देखा: gcc.gnu.org/oniltocs/libstdc++/manual/…
जिम माइकल्स

जवाबों:


240

आप इसे मेक - ग्नू मेक के साथ कर सकते हैं - यह जे-फ्लैग है (यह एक यूनिप्रोसेसर मशीन पर भी मदद करेगा)।

उदाहरण के लिए अगर आप 4 समानांतर नौकरी करना चाहते हैं:

make -j 4

आप एक पाइप में gcc भी चला सकते हैं

gcc -pipe

यह संकलन चरणों को पाइप करेगा, जो कोर को व्यस्त रखने में भी मदद करेगा।

यदि आपके पास अतिरिक्त मशीनें भी उपलब्ध हैं, तो आप डिस्टेक की जांच कर सकते हैं , जो फार्म को उन लोगों के लिए भी संकलित करेगा।


36
आप -j संख्या आपके पास मौजूद कोर की संख्या 1.5x होनी चाहिए।
मार्क बेकविथ

2
धन्यवाद। मैं CFLAGS / CPPFLAGS / CXXFLAGS के माध्यम से gcc करने के लिए "-j #" पास करने का प्रयास करता रहा। मैं पूरी तरह से भूल गया था कि "-j #" जीएनयू मेक के लिए एक पैरामीटर था (और जीसीसी के लिए नहीं)।
chriv

33
GNU मेक के लिए -j विकल्प को CPU कोर की संख्या 1.5 x करने की आवश्यकता क्यों है ?
bitek

28
1.5 संख्या की वजह से ध्यान दिया है मैं / हे बाध्य समस्या। यह अंगूठे का एक नियम है। लगभग 1/3 नौकरियां I / O की प्रतीक्षा कर रही हैं, इसलिए शेष नौकरियां उपलब्ध कोर का उपयोग कर रही होंगी। कोर की तुलना में अधिक संख्या बेहतर है और आप 2x तक भी जा सकते हैं । यह भी देखें: गन्नू ने -jतर्क दिया
कलाहीन शोर

4
@JimMichaels ऐसा इसलिए हो सकता है क्योंकि निर्भरताएँ आपके प्रोजेक्ट के भीतर बुरी तरह से सेट हो जाती हैं, (एक टारगेट तब भी बनना शुरू होता है, जब तक कि उसकी निर्भरताएँ अभी तक तैयार न हों) ताकि केवल एक क्रमिक निर्माण ही सफल हो।
एंटोनियो

42

ऐसा कोई ध्वज नहीं है, और यूनिक्स के दर्शन के खिलाफ एक रन होने से प्रत्येक उपकरण केवल एक कार्य करते हैं और इसे अच्छी तरह से करते हैं। संकलक प्रक्रियाओं का निर्माण वैचारिक रूप से निर्माण प्रणाली का काम है। आप शायद जो देख रहे हैं, वह (जॉब्स) झंडा है GNU मेक, ला

मेक -j4

या आप pmake या समान समानांतर मेक सिस्टम का उपयोग कर सकते हैं।



3
"यूनिक्स पांडेंट्री मददगार नहीं है" अच्छी बात यह है कि तब पांडित्य नहीं था, गुमनाम संपादक। पीछे लेना। समीक्षक कृपया ध्यान दें कि आप क्या कर रहे हैं।
ऑर्बिट में हल्कापन दौड़

12

लोगों ने उल्लेख किया है makeलेकिन bjamएक समान अवधारणा का समर्थन भी करते हैं। समवर्ती आदेशों bjam -jxका निर्माण करने के लिए निर्देश bjam का उपयोग करना x

हम विंडोज और लिनक्स पर एक ही बिल्ड स्क्रिप्ट का उपयोग करते हैं और इस विकल्प का उपयोग करके दोनों प्लेटफॉर्म पर हमारे बिल्ड समय को आधा कर देते हैं। अच्छा लगा।


9

makeआपके लिए यह करेंगे। मैन पेज में -jऔर -lस्विच की जांच करें । मुझे नहीं लगता कि g++यह समानांतर है।


-lविकल्प का उल्लेख करने के लिए +1 (तब तक कोई नया काम शुरू नहीं करता है जब तक कि पिछली सभी नौकरियां समाप्त न हो जाएं)। अन्यथा ऐसा लगता है कि लिंकर का काम सभी ऑब्जेक्ट फ़ाइलों के साथ शुरू नहीं हुआ है (जैसा कि कुछ संकलन अभी भी चल रहे हैं), ताकि लिंकर जॉब विफल हो जाए।
NGI

8

यदि बनाने का उपयोग कर रहे हैं, तो जारी करें -j। से man make:

  -j [jobs], --jobs[=jobs]
       Specifies the number of jobs (commands) to run simultaneously.  
       If there is more than one -j option, the last one is effective.
       If the -j option is given without an argument, make will not limit the
       number of jobs that can run simultaneously.

और सबसे विशेष रूप से, यदि आप अपने द्वारा उपलब्ध कोर की संख्या की स्क्रिप्ट या पहचान करना चाहते हैं (आपके वातावरण के आधार पर, और यदि आप कई वातावरणों में चलते हैं, तो यह बहुत बदल सकता है) आप सर्वव्यापी पायथन फ़ंक्शन का उपयोग कर सकते हैं cpu_count():

https://docs.python.org/3/library/multiprocessing.html#multiprocessing.cpu_count

ऐशे ही:

make -j $(python3 -c 'import multiprocessing as mp; print(int(mp.cpu_count() * 1.5))')

यदि आप पूछ रहे हैं कि 1.5मैं ऊपर टिप्पणी में उपयोगकर्ता को आर्टलेस-शोर क्यों उद्धृत करूंगा:

1.5 नंबर विख्यात I / O बाध्य समस्या के कारण है। यह अंगूठे का एक नियम है। लगभग 1/3 नौकरियां I / O की प्रतीक्षा कर रही हैं, इसलिए शेष नौकरियां उपलब्ध कोर का उपयोग कर रही होंगी। कोर की तुलना में अधिक संख्या बेहतर है और आप 2x तक भी जा सकते हैं।


5
: अधिकांश लिनक्स उपयोगकर्ताओं की संभावना कम पसंद करते हैं जाएगा make -j`nproc` के साथ nprocGNU coreutils में।
सिरो सेंटिल्ली 郝海东 i i i 法轮功 '25

यदि आप एक SSD का उपयोग कर रहे हैं, तो I / O एक समस्या के रूप में नहीं होगा। बस ऊपर दिए गए Ciro की टिप्पणी पर निर्माण करने के लिए, आप यह कर सकते हैं: make -j $(( $(nproc) + 1 ))(सुनिश्चित करें कि आपने उन जगहों को रखा है जहां मेरे पास है)।
एड के

अजगर पर अच्छा सुझाव, सिस्टम पर nprocउपलब्ध नहीं है, जैसे manylinux1कंटेनरों में, यह चलने से बचने से अतिरिक्त समय बचाता है yum update/ yum install
hoefling

7

डिस्टेक का उपयोग केवल वर्तमान मशीन पर ही नहीं, बल्कि डिस्टेक स्थापित करने वाले फार्म में अन्य मशीनों पर भी संकलन वितरित करने के लिए किया जा सकता है।


+1, distcc बड़े बिल्ड के लिए किसी के शस्त्रागार में एक उपयोगी उपकरण है।
फ्लेक्सो

ऐसा लगता है कि कुछ ऐसे काम हैं जो "जैसे" डिस्टेक के रूप में अच्छी तरह से करते हैं: stackoverflow.com/questions/5374106/distributed-make/…
rogerdpack

3

मुझे g ++ के बारे में निश्चित नहीं है, लेकिन अगर आप GNU मेक यू का उपयोग कर रहे हैं तो "मे -j N" (जहाँ N थ्रेड्स की संख्या बना सकते हैं) एक ही समय में मल्टी जी g ++ जॉब चलाने की अनुमति देगा (इसलिए लंबे समय तक चूंकि फाइलें एक-दूसरे पर निर्भर नहीं होती हैं)।


2
no N ist थ्रेड्स की संख्या नहीं है! बहुत से लोग इस बात को गलत समझते हैं, लेकिन यह -j Nबताता है कि एक बार में कितनी प्रक्रियाएँ होनी चाहिए, धागे नहीं। यही कारण है कि यह एमएस cl -MT(वास्तव में मल्टीथ्रेडेड) के रूप में प्रदर्शन करने वाला नहीं है ।
सेबी 2020

2

जीएनयू समानांतर

मैं एक सिंथेटिक संकलन बेंचमार्क बना रहा था और इसे मेकफाइल लिखने के लिए परेशान नहीं किया जा सकता था, इसलिए मैंने इसका इस्तेमाल किया:

sudo apt-get install parallel
ls | grep -E '\.c$' | parallel -t --will-cite "gcc -c -o '{.}.o' '{}'"

स्पष्टीकरण:

  • {.} इनपुट तर्क लेता है और उसका विस्तार हटाता है
  • -t हमें प्रगति का विचार देने के लिए चलाए जा रहे आदेशों को छापता है
  • --will-cite यदि आप इसका उपयोग करके परिणाम प्रकाशित करते हैं तो सॉफ़्टवेयर का हवाला देने का अनुरोध निकाल देता है ...

parallel इतना सुविधाजनक है कि मैं खुद भी एक टाइमस्टैम्प की जांच कर सकता हूं:

ls | grep -E '\.c$' | parallel -t --will-cite "\
  if ! [ -f '{.}.o' ] || [ '{}' -nt '{.}.o' ]; then
    gcc -c -o '{.}.o' '{}'
  fi
"

xargs -Pसमानांतर में भी नौकरी चला सकते हैं, लेकिन विस्तार में हेरफेर करना या इसके साथ कई कमांड चलाना थोड़ा कम सुविधाजनक है: xargs के माध्यम से कई कमांड को कॉल करना

समानांतर लिंकिंग में पूछा गया था: क्या लिंक करते समय कई कोर का उपयोग किया जा सकता है?

TODO: मुझे लगता है कि मैंने कहीं पढ़ा है कि मैट्रिक्स गुणन में संकलन को कम किया जा सकता है, इसलिए शायद बड़ी फ़ाइलों के लिए एकल फ़ाइल संकलन को गति देना भी संभव है। लेकिन मुझे अब संदर्भ नहीं मिल रहा है।

उबंटू 18.10 में परीक्षण किया गया।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.