2010-11-29 20 views
5

मैं सामान्य रूप से स्कैला के लिए नया हूं और विशेष रूप से अभिनेता हूं और मेरी समस्या इतनी बुनियादी है, मैंने पाया है कि ऑनलाइन संसाधन इसे कवर नहीं करते हैं।कोर का उपयोग करने के लिए अभिनेताओं का उपयोग

मैं एक सीपीयू प्रधान, आसानी से parallelized एल्गोरिथ्म है कि एक n कोर मशीन पर चलने दिया जाएगा (मैं नहीं जानता कि n)। मैं इसे अभिनेताओं में कैसे कार्यान्वित करूं ताकि सभी उपलब्ध कोर समस्या का समाधान कर सकें?

पहला रास्ता मैं सरल तोड़ने के लिए मीटर टुकड़े (जहां मीटर 10,000 जैसे कुछ मध्यम संख्या है) में समस्या थी के बारे में सोचा और मीटर अभिनेता, प्रत्येक टुकड़े के लिए एक बनाने के लिए, प्रत्येक अभिनेता अपनी छोटी सी देना टुकड़ा और चलो जाओ।

किसी भी तरह, यह मुझे अक्षम के रूप में मारा। अभिनेताओं के ज़िलियन बस लटकते हैं, कुछ सीपीयू प्यार की प्रतीक्षा करते हैं, निर्विवाद रूप से संदर्भों को बदलते हैं ...

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

मैंने पर्यवेक्षक के साथ चारों ओर नूडल किया जो जानता था कि कौन से अभिनेता व्यस्त थे, और अंत में एहसास हुआ कि यह एक हल समस्या है। इस बहुत ही सामान्य मुद्दे से निपटने के लिए एक मानक पैटर्न (शायद एक मानक पुस्तकालय) होना चाहिए। कोई सुझाव?

उत्तर

8

Akka लाइब्रेरी पर एक नज़र डालें, जिसमें अभिनेताओं का एक कार्यान्वयन शामिल है। Dispatchers Module आपको कलाकारों को सीपीयू थ्रेड्स (हौटडिस्पेच-आधारित ईवेंट-संचालित) और/या वर्कलोड को संतुलित करने (कार्य-चोरी घटना-आधारित) को सीमित करने के लिए अधिक विकल्प प्रदान करता है।

3

आपको लगता है कि आपको भविष्य में फ्यूचर्स देखना चाहिए। वास्तव में, आपको शायद एक थ्रेडपूल की आवश्यकता होती है जो थ्रेड की अधिकतम संख्या तक पहुंचने पर थ्रेड को कतार में लाती है। http://blog.tackley.net/2010/01/scala-futures.html

मैं भी सुझाव है कि आप वास्तव में आप के बाद से स्विचन संदर्भ के लिए बहुत अधिक ध्यान नहीं देते हैं कुछ नहीं कर सकते लेकिन अंतर्निहित कार्यान्वयन पर भरोसा करते हैं:

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

ध्यान दें कि मुझे नहीं पता कि सामान्य रूप से अभिनेता या वायदा इस तरह के पूल के साथ लागू किए जाते हैं या नहीं।

धागा पूल के लिए, इस पर नज़र डालें: http://www.scala-lang.org/api/current/scala/concurrent/ThreadPoolRunner.html

और हो सकता है यह: http://www.scala-lang.org/api/current/scala/actors/scheduler/ResizableThreadPoolScheduler.html

गुड लक

वायदा का उपयोग कर संपादित

कोड के इस टुकड़े की जाँच करें:

import scala.actors.Futures._ 

object FibFut { 
    def fib(i: Int): Int = if (i < 2) 1 else fib(i - 1) + fib(i - 2) 
    def main(args: Array[String]) { 
    val fibs = for (i <- 0 to 42) yield future { fib(i) } 
    for (future <- fibs) println(future()) 
    } 
} 

यह वायदा के बारे में एक बहुत अच्छा बिंदु दिखाता है, अर्थात् आप निर्णय प्राप्त करने के लिए किस क्रम में निर्णय लेते हैं (सामान्य मेलबॉक्स-प्रणाली के विपरीत जो एक फीफो सिस्टम को नियोजित करता है यानी सबसे तेज़ अभिनेता पहले अपना परिणाम भेजता है)।

0

किसी भी महत्वपूर्ण परियोजना के लिए, मेरे पास आम तौर पर एक पर्यवेक्षक अभिनेता होता है, जो कार्यकर्ता अभिनेताओं का संग्रह होता है, जिनमें से प्रत्येक कोई भी आवश्यक काम कर सकता है, और काम करने के लिए बड़ी संख्या में काम कर सकते हैं। भले ही मैं इसे अक्सर करता हूं, मैंने इसे कभी भी (व्यक्तिगत) लाइब्रेरी में नहीं रखा है क्योंकि ऑपरेशन हर बार इतना अलग होता है, और ओवरहेड पूरे कोडिंग प्रोजेक्ट की तुलना में काफी छोटा है।

3

आम तौर पर, 2 प्रकार के अभिनेता होते हैं: जो थ्रेड से जुड़े होते हैं (प्रति अभिनेता एक धागा), और जो 1+ थ्रेड साझा करते हैं, जो शेड्यूलर/प्रेषक के पीछे काम करते हैं जो संसाधन आवंटित करता है (= निष्पादित करने की संभावना नियंत्रित थ्रेड-पूल या एकल धागे के खिलाफ आने वाले संदेश को कार्य/संभाल लें)।

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

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

आप इस स्वचालित रूप से किया जा करने के लिए (कोर की संख्या के डिस्पैचर पूल में धागे की संख्या को समायोजित) चाहते हैं, आप का उपयोग करना चाहिए HawtDisaptch (या इसे Akka implementation है), के रूप में यह पहले प्रस्तावित किया गया था:

'HawtDispatcher' HawtDispatch थ्रेडिंग लाइब्रेरी का उपयोग करता है जो libdispatch का जावा क्लोन है। सभी इस प्रकार के प्रेषक वाले कलाकारों को एकल सिस्टम विस्तृत निश्चित आकार वाले थ्रेड पूल पर निष्पादित किया जाता है। थ्रेड के की संख्या आपके सिस्टम पर उपलब्ध कोर की संख्या से मेल खाती है। प्रेषक कलाकारों को संदेश भेजता है ताकि वे प्रेषक पर निर्माता थे।

0

Be aware of actor starvation यदि आप सामान्य अभिनेता थ्रेडपूल का उपयोग करना समाप्त करते हैं। मैं लंबे समय से चलने वाले, समवर्ती कार्य के समानांतरता को संभालने के लिए बस अपने स्वयं के एल्गोरिदम-कार्य-स्वामित्व वाले थ्रेडपूल का उपयोग कर समाप्त हुआ।

0

आगामी स्कैला 2.9 में समांतर डेटा संरचनाएं शामिल होने की उम्मीद है जो इसे कुछ उपयोगों के लिए स्वचालित रूप से संभालना चाहिए। हालांकि यह अभिनेताओं का उपयोग नहीं करता है, यह आपकी समस्या के लिए विचार करने के लिए कुछ हो सकता है।

हालांकि यह सुविधा मूल रूप से 2.8 के लिए निर्धारित की गई थी, इसे अगली बड़ी रिलीज तक स्थगित कर दिया गया है।

पिछले ScalaDays से एक प्रस्तुति यहाँ है:

http://days2010.scala-lang.org/node/138/140

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