Scala Language
समानांतर संग्रह
खोज…
टिप्पणियों
समानांतर संग्रह निम्न-स्तरीय समानांतरण विवरण को छिपाकर समानांतर प्रोग्रामिंग की सुविधा प्रदान करता है। यह मल्टी-कोर आर्किटेक्चर का लाभ उठाना आसान बनाता है। समानांतर संग्रहों के उदाहरणों में ParArray
, ParVector
, mutable.ParHashMap
, immutable.ParHashMap
और ParRange
। एक पूरी सूची प्रलेखन में पाई जा सकती है।
समानांतर संग्रह बनाना और उपयोग करना
अनुक्रमिक संग्रह से एक समानांतर संग्रह बनाने के लिए, par
विधि को कॉल करें। समानांतर संग्रह से अनुक्रमिक संग्रह बनाने के लिए, seq
विधि को कॉल करें। यह उदाहरण दिखाता है कि आप कैसे एक नियमित Vector
को एक ParVector
में ParVector
, और फिर फिर से वापस आते हैं:
scala> val vect = (1 to 5).toVector
vect: Vector[Int] = Vector(1, 2, 3, 4, 5)
scala> val parVect = vect.par
parVect: scala.collection.parallel.immutable.ParVector[Int] = ParVector(1, 2, 3, 4, 5)
scala> parVect.seq
res0: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 4, 5)
par
पद्धति का जंजीर बनाया जा सकता है, जिससे आप अनुक्रमिक संग्रह को एक समानांतर संग्रह में बदल सकते हैं और तुरंत उस पर कार्रवाई कर सकते हैं:
scala> vect.map(_ * 2)
res1: scala.collection.immutable.Vector[Int] = Vector(2, 4, 6, 8, 10)
scala> vect.par.map(_ * 2)
res2: scala.collection.parallel.immutable.ParVector[Int] = ParVector(2, 4, 6, 8, 10)
इन उदाहरणों में, कार्य वास्तव में कई प्रसंस्करण इकाइयों के लिए पार्सल किया गया है, और फिर डेवलपर के हस्तक्षेप की आवश्यकता के बिना काम पूरा होने के बाद फिर से शामिल हो गया है।
नुकसान
जब एक विशिष्ट क्रम में संग्रह तत्व प्राप्त होने चाहिए, तो समानांतर संग्रहों का उपयोग न करें।
समानांतर संग्रह समवर्ती संचालन करते हैं। इसका मतलब है कि सभी काम भागों में विभाजित हैं और विभिन्न प्रोसेसर को वितरित किए गए हैं। प्रत्येक प्रोसेसर दूसरों द्वारा किए जा रहे काम से अनजान है। यदि संग्रह का क्रम मायने रखता है, तो समानांतर में संसाधित कार्य नॉनडेटर्मिनिस्टिक है। (एक ही कोड को दो बार चलाने से अलग-अलग परिणाम मिल सकते हैं।)
गैर-सहयोगी संचालन
यदि कोई ऑपरेशन गैर-सहयोगी है (यदि निष्पादन का क्रम मायने रखता है), तो एक समानांतर संग्रह पर परिणाम नॉनडेर्मेट्रिस्टिक होगा।
scala> val list = (1 to 1000).toList
list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10...
scala> list.reduce(_ - _)
res0: Int = -500498
scala> list.reduce(_ - _)
res1: Int = -500498
scala> list.reduce(_ - _)
res2: Int = -500498
scala> val listPar = list.par
listPar: scala.collection.parallel.immutable.ParSeq[Int] = ParVector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10...
scala> listPar.reduce(_ - _)
res3: Int = -408314
scala> listPar.reduce(_ - _)
res4: Int = -422884
scala> listPar.reduce(_ - _)
res5: Int = -301748
दुष्प्रभाव
ऐसे ऑपरेशन जिनमें साइड इफेक्ट होते हैं, जैसे कि foreach
, दौड़ की स्थिति के कारण समानांतर संग्रह पर वांछित के रूप में निष्पादित नहीं किया जा सकता है। ऐसे कार्यों का उपयोग करने से बचें, जिनके कोई दुष्प्रभाव नहीं हैं, जैसे कि reduce
या map
।
scala> val wittyOneLiner = Array("Artificial", "Intelligence", "is", "no", "match", "for", "natural", "stupidity")
scala> wittyOneLiner.foreach(word => print(word + " "))
Artificial Intelligence is no match for natural stupidity
scala> wittyOneLiner.par.foreach(word => print(word + " "))
match natural is for Artificial no stupidity Intelligence
scala> print(wittyOneLiner.par.reduce{_ + " " + _})
Artificial Intelligence is no match for natural stupidity
scala> val list = (1 to 100).toList
list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15...