2013-02-25 18 views
11

मैं कस्टम सर्वर को कार्यान्वित कर रहा हूं जिसे बहुत लंबे समय तक रहने वाले कनेक्शन (100K या अधिक) बनाए रखने की आवश्यकता है। सर्वर बस सॉकेट के बीच संदेश पास करता है और यह कोई गंभीर डेटा प्रोसेसिंग नहीं करता है। संदेश छोटे होते हैं, लेकिन उनमें से कई को हर सेकेंड प्राप्त/भेज दिया जाता है। विलंबता को कम करना लक्ष्यों में से एक है। मुझे एहसास है कि एकाधिक कोर का उपयोग प्रदर्शन में सुधार नहीं करेगा और इसलिए मैंने run_one या pollio_service ऑब्जेक्ट के तरीकों को कॉल करके सर्वर को एक थ्रेड में चलाने का निर्णय लिया। वैसे भी बहु थ्रेडेड सर्वर लागू करने के लिए बहुत कठिन होगा।बूस्ट एएसओ एकल थ्रेडेड प्रदर्शन

संभावित बाधाएं क्या हैं? Syscalls, बैंडविड्थ, समापन कतार/घटना demultiplexing? मुझे संदेह है कि प्रेषक हैंडलर को लॉकिंग की आवश्यकता हो सकती है (जो आंतरिक रूप से एएसओ लाइब्रेरी द्वारा किया जाता है)। Boost.asio में कतार लॉकिंग (या कोई अन्य लॉकिंग) भी अक्षम करना संभव है?

संपादित करें: संबंधित प्रश्न। Syscall प्रदर्शन एकाधिक धागे के साथ सुधार करता है? मेरी भावना यह है कि क्योंकि सिस्को कर्नेल द्वारा परमाणु/सिंक्रनाइज़ किए जाते हैं, इसलिए अधिक धागे गति में सुधार नहीं करेंगे।

+0

यदि आप सब कुछ एक थ्रेड में चला रहे हैं, तो आपको किसी भी (हस्तलिखित) ताले की आवश्यकता नहीं है। –

+1

एकाधिक कोर का उपयोग करने से प्रदर्शन में सुधार होगा - पिछले साल मैंने किए गए कुछ बेंचमार्क के लिए http://cmeerw.org/blog/748.html#748 और http://cmeerw.org/blog/746.html#746 देखें। – cmeerw

उत्तर

15

कुछ साल पहले आप my question पढ़ना चाहेंगे, मैंने पहले पूछा था कि Blue Gene/Q supercomputer के लिए सिस्टम सॉफ़्टवेयर विकसित करते समय बूस्ट.एएसियो की स्केलेबिलिटी की जांच करते समय।

100k या अधिक कनेक्शन के लिए स्केलिंग कोई समस्या नहीं होनी चाहिए, हालांकि आपको खुली फ़ाइल डिस्क्रिप्टर की अधिकतम संख्या जैसे स्पष्ट संसाधन सीमाओं से अवगत होना होगा। यदि आपने seminal C10K paper नहीं पढ़ा है, तो मैं इसे पढ़ने का सुझाव देता हूं।

के बाद आप अपने आवेदन के लिए एक एकल धागा और एक एकल io_service का उपयोग कर लागू कर दिया है, मैं धागे io_service::run() लागू का एक पूल की जांच का सुझाव देते हैं, और उसके बाद ही एक विशिष्ट थ्रेड और/या CPU के लिए एक io_service pinning की जांच। इन तीनों डिज़ाइनों के लिए एएसओ दस्तावेज़ में कई उदाहरण शामिल हैं, और अधिक जानकारी के साथ SO पर several questions शामिल हैं।ध्यान रखें कि जब आप io_service::run() का आह्वान करते हुए कई धागे पेश करते हैं तो आपको यह सुनिश्चित करने के लिए strand एस लागू करने की आवश्यकता हो सकती है कि हैंडलर के पास साझा डेटा संरचनाओं तक विशेष पहुंच हो।

9

बूस्ट :: एएसओओ का उपयोग करके आप सिंगल-थ्रेड या मल्टी-थ्रेड सर्वर को लगभग उसी विकास लागत पर लिख सकते हैं। आप सिंगल थ्रेडेड वर्जन को पहले संस्करण के रूप में लिख सकते हैं, फिर आवश्यक होने पर इसे मल्टीथ्रेडेड में परिवर्तित कर सकते हैं।

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

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

इसके अलावा, आप io_service को अलग कर सकते हैं और इसे "io_service प्रति थ्रेड" idiom के रूप में काम कर सकते हैं। मुझे लगता है कि यह सबसे अच्छा प्रदर्शन देना चाहिए, लेकिन इसमें कमी है: यदि io_service में से एक बहुत बड़ी कतार प्राप्त करेगी - अन्य धागे इसकी मदद नहीं करेंगे, इसलिए कुछ कनेक्शन मंदी हो सकते हैं। दूसरी ओर, एकल io_service के साथ - कतार ओवररन बड़े लॉकिंग ओवरहेड का कारण बन सकता है। आप बस कर सकते हैं - दोनों प्रकारों को करें और बैंडविड्थ/विलंबता को मापें। दोनों प्रकारों को लागू करना बहुत मुश्किल नहीं होना चाहिए।

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