2014-08-31 4 views
5

मेरे पास एक सीपीयू गहन कार्य है (कुछ डेटा के माध्यम से लूपिंग और परिणामों का मूल्यांकन)। मैं इनके लिए एकाधिक कोर का उपयोग करना चाहता हूं लेकिन मेरा प्रदर्शन केवल एक कोर का उपयोग करने से भी बदतर है।नोडजेस - मुझे मल्टीथ्रेडिंग मिल रही है या एकाधिक प्रक्रियाओं का उपयोग करना एक प्रक्रिया से धीमा है। क्यूं कर?

मैं कोशिश की है:

  • express के साथ विभिन्न बंदरगाहों पर कई प्रक्रियाओं बनाना और थ्रेड पूल
का उपयोग कर इन प्रक्रियाओं
  • को कार्य भेजने अलग धागे में कार्यों को चलाने के लिए webworker-threads का उपयोग करना

    मैं पुनरावृत्ति की कुल संख्या की गणना करके परिणामों को माप रहा हूं, मैं समस्या पर काम करने में कितने समय तक पूरा कर सकता हूं और विभाजित कर सकता हूं। एक कोर का उपयोग करते समय, मेरे परिणाम काफी बेहतर होते हैं।

    हित के कुछ अंक:

    • मैं जब मैं सिर्फ एक कोर का उपयोग कर रहा पहचान कर सकते हैं और जब मैं कार्य प्रबंधक के माध्यम से कई कोर का उपयोग कर रहा हूँ। मैं कोर की अपेक्षित संख्या का उपयोग कर रहा हूं।
    • मैं
    • मैं कोशिश की सिर्फ 2 या 3 कोर पर चल गया है राम की बहुत सारी
    • मैं जोड़ा nextTicks जो इस मामले में कुछ भी प्रभाव दिखाई नहीं देता
    • कार्य कई सेकंड प्रत्येक तो मैं ले ऐसा महसूस न करें कि मैं ओवरहेड पर बहुत कुछ खो रहा हूं

    कोई विचार क्या है कि यहां क्या हो रहा है? धागे के लिए

    अद्यतन: मैं WebWorker-धागे में एक बग संदेह है अब के लिए एक्सप्रेस छोड़ा जा रहा है, मुझे लगता है कि इस मुद्दे को मेरी धागा पाश से कोई लेना देना पड़ सकता है। मैं जो कर रहा हूं वह एक थ्रेड बना रहा है और फिर लगातार उन्हें चलाने की कोशिश कर रहा है लेकिन उनके बीच डेटा भेजता है। भले ही दोनों धागे CPU का उपयोग कर रहे हों, केवल धागा 0 मूल्यों को वापस कर रहा है। मेरी धारणा उत्सर्जित थी कि आम तौर पर किसी भी थ्रेड को संदेश को उत्सर्जित करना समाप्त हो गया था जो कि सबसे लंबे समय तक निष्क्रिय था लेकिन ऐसा लगता है कि ऐसा नहीं लगता है। मेरे सेट अप threadtask.js

    thread.on('init', function() { 
    
        thread.emit('ready'); 
    
        thread.on('start', function(data) { 
         console.log("THREAD " + thread.id + ": execute task"); 
         //... 
         console.log("THREAD " + thread.id + ": emit result"); 
         thread.emit('result', otherData)); 
        }); 
    }); 
    

    main.js

    var tp = Threads.createPool(NUM_THREADS); 
    tp.load(threadtaskjsFilePath); 
    var readyCount = 0; 
    tp.on('ready', function() { 
        readyCount++; 
    
        if(readyCount == tp.totalThreads()) { 
         console.log('MAIN: Sending first start event'); 
         tp.all.emit('start', JSON.stringify(data)); 
        } 
    }); 
    
    tp.on('result', function(eresult) { 
        var result = JSON.parse(eresult); 
        console.log('MAIN: result from thread ' + result.threadId); 
        //... 
        console.log('MAIN: emit start' + result.threadId); 
        tp.any.emit('start' + result.threadId, data); 
    }); 
    
    tp.all.emit("init", JSON.stringify(data2)); 
    

    इस आपदा के उत्पादन के भीतर इस

    की तरह लग रहा

    MAIN: Sending first start event 
    THREAD 0: execute task 
    THREAD 1: execute task 
    THREAD 1: emit result 
    MAIN: result from thread 1 
    THREAD 0: emit result 
    THREAD 0: execute task 
    THREAD 0: emit result 
    MAIN: result from thread 0 
    MAIN: result from thread 0 
    THREAD 0: execute task 
    THREAD 0: emit result 
    THREAD 0: execute task 
    THREAD 0: emit result 
    MAIN: result from thread 0 
    MAIN: result from thread 0 
    THREAD 0: execute task 
    THREAD 0: emit result 
    THREAD 0: execute task 
    THREAD 0: emit result 
    MAIN: result from thread 0 
    MAIN: result from thread 0 
    

    मैं कोशिश की थी एक और दृष्टिकोण भी जहां मैं सभी को छोड़ दूंगा लेकिन तब प्रत्येक थ्रेड एक संदेश के लिए सुनेंगे जो केवल इसका जवाब दे सकता है। उदाहरण के लिए, thread.on ('शुरू करें' + thread.id, फ़ंक्शन() {...})। यह काम नहीं करता है क्योंकि परिणामस्वरूप जब मैं tp.all.emit ('start' + result.threadId, ...) करता हूं, तो संदेश उठाया नहीं जाता है।

    MAIN: Sending first start event 
    THREAD 0: execute task 
    THREAD 1: execute task 
    THREAD 1: emit result 
    THREAD 0: emit result 
    

    इसके बाद और कुछ नहीं होता है।

    कई एक्सप्रेस सर्वर के लिए अद्यतन: मैं सुधार हो रही है लेकिन उम्मीद

    से मैं इस समाधान पर दोबारा गौर किया और अधिक किस्मत ने छोटे। मुझे लगता है कि मेरा मूल माप त्रुटिपूर्ण हो सकता है। नए परिणाम:

    • एकल प्रक्रिया: 3.3 पुनरावृत्तियों/सेकंड
    • मुख्य प्रक्रिया + 2 सर्वर: 4.2 पुनरावृत्तियों/सेकंड
    • मुख्य प्रक्रिया + 3 सर्वर: 4.9 पुनरावृत्तियों/सेकंड

    एक बात मुझे थोड़ा अजीब लगता है कि मैं 2 सर्वरों के लिए लगभग 6 पुनरावृत्तियों/सेकंड और 3 के लिए 9 नहीं देख रहा हूं। मुझे लगता है कि नेटवर्किंग के लिए कुछ नुकसान हैं लेकिन यदि मैं अपना कार्य समय पर्याप्त रूप से उच्च करने के लिए बढ़ाता हूं, तो नेटवर्क नुकसान मुझे लगता है कि बहुत मामूली हो।

  • +1

    क्या आप वाकई सीपीयू बाध्य हैं और आईओ बाध्य नहीं हैं? –

    +0

    काफी निश्चित है। क्या आप जानते हैं कि मैं कैसे पुष्टि कर सकता हूं कि यह आईओ बाध्य नहीं है? थ्रेड प्रारंभ होने के बाद मैं डिस्क से कुछ भी लोड नहीं कर रहा हूं। मैं थ्रेड पर आगे और पीछे कुछ जेसन सरणी भेज रहा हूं लेकिन वे बहुत बड़े नहीं हैं। – i8abug

    +0

    डिस्क/नेटवर्क उपयोग पर नजर रखें और देखें कि क्या यह लगता है कि आप –

    उत्तर

    1

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

    मुझे वेब श्रमिक पैकेज सिंक्रनाइज़ेशन को संभालने के तरीके की जटिलताओं को नहीं जानता है, c स्पेस इत्यादि में होने वाले नोड.जेएस के I/O थ्रेड पूल को प्रभावित करता है, लेकिन मेरा मानना ​​है कि आप आमतौर पर वेब श्रमिकों को पेश करना चाहते हैं के बिना एक ही समय में अधिक अवरुद्ध कार्यों को प्रबंधित करने में सक्षम होने के लिए गंभीर रूप से अन्य अनुरोधों को प्रभावित करते हैं जिनके लिए कोई थ्रेडिंग और सिस्टम I/O की आवश्यकता नहीं होती है, या अन्यथा शीघ्रता से प्रतिक्रिया दी जा सकती है। इसका जरूरी अर्थ यह नहीं है कि इसे लागू करने से विशेष कार्यों के लिए प्रदर्शन में सुधार होगा। यदि आप 4 प्रक्रियाओं को 4 थ्रेड के साथ चलाते हैं जो I/O करते हैं, तो आप एप्लिकेशन स्पेस के बाहर थ्रेड संदर्भों के बीच लगातार स्विचिंग समय बर्बाद कर सकते हैं।

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