2011-08-13 26 views
7

टीएल; डीआर: क्या यह संभव है कि मैं रिएक्टर थ्रूपुट सीमित हूं? मैं कैसे बताऊंगा? कितना महंगा और स्केलेबल (धागे में) io_service का कार्यान्वयन है?बूस्ट एएसआईओ रिएक्टर से बचने के लिए कैसे एक कोर को बाध्य किया जा रहा है?

मेरे पास एक बड़े पैमाने पर समानांतर अनुप्रयोग है, जो एक हाइपरथ्रेडेड-डुअल-क्वाड-कोर-ज़ीऑन मशीन पर चल रहा है जिसमें बहुत सी रैम और तेज एसएसडी RAID है। यह boost :: asio का उपयोग करके विकसित किया गया है।

यह एप्लिकेशन लगभग 1,000 अन्य मशीनों से कनेक्शन स्वीकार करता है, डेटा पढ़ता है, एक साधारण प्रोटोकॉल डीकोड करता है, और एमएमएपी() का उपयोग करके मैप किए गए फ़ाइलों में डेटा को शफ़ल करता है। एप्लिकेशन मैडवाइस (विल्नेड) का उपयोग करके "भविष्य" एमएमएपी पृष्ठों को भी पूर्व-प्राप्त करता है, इसलिए पेज दोषों पर अवरुद्ध होने की संभावना नहीं है, लेकिन यह सुनिश्चित करने के लिए कि मैंने 300 धागे तक पहुंचने की कोशिश की है।

यह लिनक्स कर्नेल 2.6.32-27-जेनेरिक (उबंटू सर्वर x64 एलटीएस 10.04) पर चल रहा है। जीसीसी संस्करण 4.4.3 है और बूस्ट :: एएसओ संस्करण 1.40 है (दोनों स्टॉक उबंटू एलटीएस हैं)।

vmstat, iostat और top चल रहा है, मुझे लगता है कि डिस्क थ्रूपुट (टीपीएस और डेटा वॉल्यूम दोनों में)% के एकल अंकों पर है। इसी तरह, डिस्क कतार की लंबाई हमेशा धागे की संख्या से बहुत छोटी होती है, इसलिए मुझे नहीं लगता कि मैं I/O बाध्य हूं। इसके अलावा, आरएसएस चढ़ता है लेकिन फिर कुछ गीग्स (अपेक्षित के रूप में) पर स्थिर हो जाता है और vmstat कोई पेजिंग नहीं दिखाता है, इसलिए मुझे लगता है कि मैं स्मृति बाध्य नहीं हूं। सीपीयू 0-1% उपयोगकर्ता, 6-7% सिस्टम और शेष निष्क्रिय के रूप में स्थिर है। सुराग! एक पूर्ण "कोर" (हाइपर-थ्रेडिंग याद रखें) CPU का 6.25% है।

मुझे पता है कि सिस्टम पीछे गिर रहा है, क्योंकि क्लाइंट मशीन टीसीपी पर ब्लॉक करती है जब 64kb से अधिक बकाया है, और तथ्य की रिपोर्ट करें; वे सभी इस तथ्य की रिपोर्ट करते रहते हैं, और प्रणाली के माध्यम से थ्रूपुट वांछित, इरादा, और सैद्धांतिक रूप से संभव से बहुत कम है।

मेरा अनुमान है कि मैं किसी प्रकार के लॉक पर विरोध कर रहा हूं। मैं एक लुक-अप तालिका को संरक्षित करने के लिए एप्लिकेशन-स्तरीय लॉक का उपयोग करता हूं जिसे उत्परिवर्तित किया जा सकता है, इसलिए मैंने इसे निर्भरता को तोड़ने के लिए इसे 256 शीर्ष-स्तरीय ताले/तालिकाओं में शेड किया। हालांकि, यह बिल्कुल मदद नहीं कर रहा था।

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

क्या यह संभव है कि मैं रिएक्टर थ्रूपुट सीमित हूं? मैं कैसे बताऊंगा? कितना महंगा और स्केलेबल (धागे में) io_service का कार्यान्वयन है?

संपादित करें: मुझे शुरुआत में यह अन्य धागा नहीं मिला क्योंकि यह टैग का एक सेट इस्तेमाल करता था जो मेरा ओवरलैप नहीं करता था: -/यह काफी संभव है कि मेरी समस्या अत्यधिक :: लॉकिंग के कार्यान्वयन में उपयोग की जा रही है रिएक्टर। C++ Socket Server - Unable to saturate CPU देखें, हालांकि सवाल यह है कि: मैं इसे कैसे साबित कर सकता हूं? और मैं इसे कैसे ठीक कर सकता हूं?

+1

क्या आपने एएसओ के नए संस्करणों का उपयोग करके प्रदर्शन की तुलना की है? बूस्ट 1.40 एक छोटा सा पुराना है और कुछ अच्छे सुधार एकीकृत हुए [काफी हाल ही में] (http://think-async.com/Asio/LinuxPerformanceImprovements)। –

+0

मैं कुछ हद तक उबंटू 10.04 एलटीएस का उपयोग करने के लिए बाध्य हूं, जो 1.40 के साथ आता है। मैं शायद इसे एक और आधुनिक प्रणाली पर परीक्षण कर सकता हूं, लेकिन इसे अभी भी स्टॉक 10.04 पर तैनाती की जरूरत है। मुझे लगता है कि boost :: asio केवल हेडर है, इसलिए शायद इसे काम करने के लिए बनाया जा सकता है ... –

+1

सैम: मैंने नवीनतम रिलीज़ बूस्ट के साथ प्रयास किया, जो कि 1.47.0 है। यह अभी भी एक ही समस्या है - प्रदर्शन एक एकल सीपीयू कोर से अधिक होने से इंकार कर देता है (हालांकि सभी कोर वास्तव में कुछ काम कर रहे हैं, बस ज्यादातर अवरुद्ध)। –

उत्तर

2

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

+0

क्या आप उस पर थोड़ा विस्तार कर सकते हैं, उदा। जहां यह स्रोत में देखा जा सकता है? मैं सिर्फ उत्सुक हूँ। :) – murrekatt

+0

@ जोन यह हो सकता है कि एएसआईओ ** का डिज़ाइन ** ** ** 'io_service' * प्रति थ्रेड * हो सकता है? और बस सुविधा के रूप में लॉकिंग प्रदान करता है ताकि आपका प्रोग्राम असफल न हो? – unixman83

+0

इसके विपरीत काफी। एएसआईओ एपीआई का कहना है कि काम सभी थ्रेडों में साझा किया जाएगा जो एक ही io_service में प्रवेश करते हैं - यह एएसआईओ का पूरा बिंदु है। जब समस्या प्रति ऑब्जेक्ट अधिसूचनाओं का पुन: आदेश दिया जा सकता है तो समस्या वास्तव में वस्तुओं का जीवनकाल है। –

2

मेरा मानना ​​है कि यदि आप एकाधिक io_service ऑब्जेक्ट (प्रत्येक सीपीयू कोर के लिए कहते हैं) का उपयोग करते हैं, तो प्रत्येक एक थ्रेड द्वारा चलाया जाता है, आपको यह समस्या नहीं होगी। एएसआईओ पृष्ठ को बढ़ावा देने पर http सर्वर उदाहरण 2 देखें।

मैंने सर्वर उदाहरण 2 और सर्वर उदाहरण 3 के खिलाफ विभिन्न मानक किए हैं और पाया है कि मैंने जो कार्यान्वयन मैंने उल्लेख किया है वह सबसे अच्छा काम करता है।

+0

समस्या यह है कि प्रत्येक I/O ऑब्जेक्ट (टाइमर, सॉकेट, आदि) को io_service पर भेज दिया जाना चाहिए, जो AFAICT है। धागे को स्थिर रूप से आवंटित सॉकेट कुछ ऐसा नहीं है जिसे मैं करना चाहता हूं। –

0

मेरे एकल थ्रेडेड एप्लिकेशन में, मुझे प्रोफाइलिंग से पता चला कि प्रोसेसर निर्देशों का एक बड़ा हिस्सा io_service :: poll() द्वारा लॉकिंग और अनलॉक करने पर खर्च किया गया था। मैंने BOOST_ASIO_DISABLE_THREADS मैक्रो के साथ लॉक ऑपरेशंस को अक्षम कर दिया। यह आपकी थ्रेडिंग स्थिति के आधार पर भी आपके लिए समझ में आ सकता है।

+0

जब आप थ्रेड समर्थन को अक्षम करते हैं, तो आप इसे केवल एक थ्रेड के साथ चला सकते हैं, जो स्पष्ट रूप से एक कोर को बाध्य नहीं होने का लक्ष्य प्राप्त नहीं करेगा। –

+0

प्रति थ्रेड एक io_service का उपयोग क्यों न करें और अभी भी लॉक-फ्री रहें? क्या यह एक अवैध उपयोग मामला है? – Syncopated

+0

क्योंकि यह सभी धागे में सभी कार्यों को स्केल करने के उद्देश्य को हरा देता है। ध्यान दें कि सॉकेट और जैसे कि कन्स्ट्रक्टर में किसी विशेष io_service से बंधे हैं। –