2012-08-23 15 views
9

मैं लूपबैक (127.0.0.1) पर लिनक्स पर एक अनुकूलित जावा एनआईओ चयनकर्ता के साथ कुछ मानक कर रहा हूं।जावा एनआईओ चयनकर्ता न्यूनतम संभव विलंबता

मेरा परीक्षण बहुत सरल है:

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

राउंड ट्रिप समय मैं निम्नलिखित परिणाम प्राप्त के लिए:

  • मिन समय: 13 माइक्रो
  • औसत समय: 19 माइक्रो
  • 75% प्रतिशतक: 18,567 nanos
  • 90% प्रतिशत: 18,78 9 नैनो
  • 99% प्रतिशत: 1 9, 184 नैनो
  • 99.9% प्रतिशत: 1 9, 64 नैनो
  • 99.99% प्रतिशतक: 19,310 nanos
  • 99.999% प्रतिशतक: 19,322 nanos

लेकिन यहाँ पकड़ है कि मैं 1 लाख संदेशों कताई कर रहा हूँ।

  • मिन समय:: 41 माइक्रो
  • औसत समय: 160 माइक्रो
  • 75% प्रतिशतक: 150,701 nanos
  • 90% प्रतिशतक

    अगर मैं केवल 10 संदेशों स्पिन मैं बहुत अलग परिणाम प्राप्त : 155,274 nanos

  • 99% प्रतिशतक: 159,995 nanos
  • 99.9% प्रतिशतक: 159,995 nanos
  • ,210
  • 99.99% प्रतिशतक: 159,995 nanos
  • 99.999% प्रतिशतक: 159,995 nanos

मुझे सही अगर मैं गलत हूँ, लेकिन मुझे लगता है कि एक बार हम कताई NIO चयनकर्ता प्राप्त प्रतिक्रिया समय इष्टतम हो जाते हैं। हालांकि अगर हम उनके बीच पर्याप्त पर्याप्त अंतराल के साथ संदेश भेज रहे हैं, तो हम चयनकर्ता को जागने की कीमत का भुगतान करते हैं।

यदि मैं सिर्फ एक संदेश भेजने के साथ खेलता हूं तो मुझे 150 से 250 माइक्रोस्कोस के बीच कई बार मिलता है।

तो समुदाय के लिए मेरे सवाल कर रहे हैं:

1 - 19 माइक्रो इस राउंड ट्रिप पैकेट परीक्षण के लिए इष्टतम की औसत के साथ 13 माइक्रो के मेरी न्यूनतम समय है। ऐसा लगता है कि मैं ZeroMQ को अब तक मार रहा हूं इसलिए मुझे यहां कुछ याद आ रहा है।इस बेंचमार्क यह ZeroMQ की तरह लग रहा से एक मानक कर्नेल पर एक 49 माइक्रो औसत समय (99% प्रतिशतक) है =>http://www.zeromq.org/results:rt-tests-v031

2 - क्या मैं जब मैं स्पिन एक या बहुत चयनकर्ता प्रतिक्रिया समय में सुधार करने के कुछ कर सकते हैं कुछ संदेश? 150 माइक्रोस अच्छा नहीं दिखता है। या मुझे लगता है कि प्रोड पर्यावरण पर चयनकर्ता काफी नहीं होगा?


selectNow() के आसपास व्यस्त कताई करके मैं बेहतर परिणाम प्राप्त करने में सक्षम हूं। कुछ पैकेट भेजना अभी भी कई पैकेट भेजने से भी बदतर है, लेकिन मुझे लगता है कि अब मैं चयनकर्ता प्रदर्शन सीमा को मार रहा हूं। मेरे परिणाम:

  • एक ही पैकेट भेजना मुझे एक सतत 65 माइक्रोस राउंड ट्रिप टाइम मिलता है।
  • दो पैकेट भेजना मुझे औसतन 39 माइक्रोस राउंड ट्रिप टाइम मिलता है।
  • 10 पैकेट भेजना मुझे औसतन 17 माइक्रोस राउंड ट्रिप टाइम मिलता है।
  • 10,000 पैकेट भेजना मुझे औसतन 10,0 9 8 नैनो राउंड ट्रिप टाइम मिलता है।
  • 1 मिलियन पैकेट भेजना मुझे औसतन 9, 9 77 नैनो राउंड ट्रिप टाइम मिलता है।

निष्कर्ष

  • तो यह यूडीपी पैकेट राउंड ट्रिप के लिए शारीरिक बाधा की तरह दिखता है 10 माइक्रोसेकंड हालांकि मैं 8 माइक्रो में कुछ यात्रा कर पैकेट मिला है (न्यूनतम समय) के एक औसत है ।

  • व्यस्त कताई (धन्यवाद पीटर) के साथ मैं औसत पर 200 माइक्रोसॉफ्ट से एक ही पैकेट के लिए औसतन 65 माइक्रोसॉफ्ट तक जाने में सक्षम था।

  • यह सुनिश्चित नहीं है कि ZeroMQ 5 times slower क्यों है। (संपादित करें: हो सकता है कि क्योंकि मैं लूपबैक और ZeroMQ के माध्यम से एक ही मशीन पर यह परीक्षण कर रहा हूँ दो अलग-अलग मशीनों का उपयोग कर रहा है?)

+0

मुझे लगता है कि इनमें से अधिकतर चयनकर्ताओं के व्यवहार के बजाय हॉटस्पॉट जेवीएम वार्मअप समय के कारण है। – EJP

+1

धन्यवाद @EJP, लेकिन मैंने जेवीएम इन-सर्वर मोड में कुछ गर्मजोशी की। मैंने संदेश भेजने से पहले कुछ मिलियन संदेश भेजे थे जो बेंचमार्क को ट्रिगर करेंगे। आपको ऐसा क्यों लगता है कि यह हो रहा है => "अगर मैं सिर्फ एक संदेश भेजने के साथ खेलता हूं तो मुझे 150 से 250 माइक्रोसॉफ्ट के बीच कई बार मिलता है।" – Julie

+0

मुझे पागल कहें लेकिन क्यों आप सी में अपने विवरण (विवरण से) लघु कार्यक्रम को फिर से लागू नहीं करते हैं और प्रदर्शन देखते हैं। – NoSenseEtAl

उत्तर

4

आप अकसर ऐसे मामले देखने के एक धागा जागने बहुत महंगा हो सकता है, सिर्फ इसलिए कि नहीं यह थ्रेड के लिए जागने में समय लगता है, लेकिन थ्रेड माइक्रो-सेकंड के लिए 2-5x धीमी गति से चलता है क्योंकि कैश और

जिस तरह से मैंने अतीत में इसे टाला है, वह व्यस्त प्रतीक्षा करना है। दुर्भाग्य से selectNow हर बार जब आप इसे खाली संग्रह करते हैं तो भी एक नया संग्रह बनाता है। यह इतना कचरा उत्पन्न करता है जिसका उपयोग करने योग्य नहीं है।

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

मैं यह भी सुझाव दूंगा कि आपका कोड लॉक कम और कचरा कम करने की कोशिश कर रहा है। यदि आप ऐसा करते हैं तो आप जावा में एक प्रक्रिया कर सकते हैं जो आने वाले पैकेट को 100 माइक्रो-सेकंड के 90% समय के भीतर प्रतिक्रिया भेजता है। यह आपको प्रत्येक पैकेट को 100 एमबी पर पहुंचने की अनुमति देगा (बैंडविड्थ सीमाओं के कारण 145 माइक्रो-सेकंड अलग) एक 1 जीबी कनेक्शन के लिए आप बहुत करीब आ सकते हैं।


आप जावा में एक ही बॉक्स पर तेजी से इंटरप्रोसेस संवाद चाहते हैं, आप विचार कर सकते हैं राउंड ट्रिप सुप्तावस्था के साथ संदेश पारित करने के लिए https://github.com/peter-lawrey/Java-Chronicle इस का उपयोग करता है साझा स्मृति की तरह कुछ (जो कठिन है सॉकेट के साथ कुशलता से करने के लिए) से भी कम की 200 नैनो-सेकंड। यह डेटा भी जारी रखता है और उपयोगी होता है यदि आप जर्नल फ़ाइल बनाने का एक तेज़ तरीका चाहते हैं।

+0

हाय पीटर। कृपया अपनी टिप्पणियों के आधार पर मेरे नए परिणाम देखें। कोई विचार क्यों ज़ीरोएमक्यू 5 गुना धीमा है? – Julie

+0

ज़ीरोएमक्यू को केवल एकल सॉकेट पर एक पैकेट भेजने से अधिक करना है। इसे और अधिक काम करना है, रूटिंग इत्यादि, इसलिए इसकी विलंबता अधिक होगी। मुझे यह भी संदेह है कि यह प्रेषण प्राप्त करने के लिए पृष्ठभूमि धागे का उपयोग करता है जो कनेक्शन पर प्रबंधन और नियंत्रण में सुधार करता है (या कम से कम इनमें से कई पुस्तकालय करते हैं) आप जो व्यापार बंद करते हैं, उनमें से एक यह है कि भेजने वाले धागे का उपयोग करके संदेश बैच करके, आप कर सकते हैं थ्रूपुट 10 गुना बढ़ाएं जो कि कई पुस्तकालय विलंबता के बजाए ध्यान केंद्रित करते हैं। –

+0

मुझे संदेह है कि अंतर यह है क्योंकि मैं इसे लूपबैक पर परीक्षण कर रहा हूं। मैं तुलना करने के लिए लूपबैक पर ज़ीरोएमक्यू बेंचमार्क खोजने की कोशिश कर रहा हूं। एक भेजने धागा !? वह भयानक है! आप चैनल लिखने को क्यों नहीं बुला सकते हैं और ओएस बाकी को क्यों कर सकते हैं? एनआईओ से अलग कुछ भी कम विलंबता के लिए गैर-समझ में आईएमएचओ है। – Julie

-1

यदि आप अपने चयनकर्ता अधिकार को ट्यून करते हैं, तो आप 2 माइक्रोसॉंड से कम में जावा में इंटर-सॉकेट संचार प्राप्त कर सकते हैं।

Iterations: 1,000,000 
Message Size: 256 bytes 
Avg Time: 1,680 nanos 
Min Time: 1379 nanos 
Max Time: 7020 nanos 
75%: avg=1618 max=1782 nanos 
90%: avg=1653 max=1869 nanos 
99%: avg=1675 max=1964 nanos 
99.9%: avg=1678 max=2166 nanos 
99.99%: avg=1679 max=5094 nanos 
99.999%: avg=1680 max=5638 nanos 

मैं अपने लेख Inter-socket communication with less than 2 microseconds latency में जावा NIO और रिएक्टर पैटर्न के बारे में अधिक बात करते हैं: यह एक 256 बाईट यूडीपी पैकेट के लिए मेरे एक तरह से परिणाम हैं।

+4

यह एक शर्म की बात है कि लेख वास्तव में यह नहीं कहता कि आपने यह कैसे किया ... –

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