Rivertrail: JavaScript में संक्षिप्त नाम



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

मैंने हाल ही में Rivertrail का उपयोग करना शुरू किया, जो Intel द्वारा जेएस में डेटा को समानांतर बनाने के लिए एक उपकरण के रूप में पेश किया गया उत्पाद है। अब तक की परियोजना केवल सकारात्मक छाप छोड़ती है। प्रारंभिक संस्करण इंटेल विनिर्देशों से बंधा होगा, लेकिन मुझे उम्मीद है कि तब इसे पीजे के ढांचे के भीतर बनाई गई अन्य परियोजनाओं के साथ संयोजन करना संभव होगा।

डमियों के लिए रिवर्ट्रियल
यहां उन लोगों के लिए एक छोटा परिचय है, जिन्होंने इस उत्पाद के बारे में पहले नहीं सुना है: रिवर्ट्रियल एक विनिर्देश है जो आपको समानांतर में एक सरणी को संसाधित करने की अनुमति देता है। विनिर्देशन का आधार ParallelArray वर्ग के अतिरिक्त है। इन सरणियों में जेएस सरणियों से कई महत्वपूर्ण अंतर हैं।
  • वे अपरिवर्तित हैं
  • अंतराल नहीं है
  • वे बहुआयामी हो सकते हैं, लेकिन बहुआयामी "सही" (उदाहरण के लिए, दो-आयामी मैट्रिक्स में स्तंभों की संख्या पंक्तियों की संख्या के बराबर होगी)।

समानांतर सरणियाँ उच्च स्तर के संचालन की काफी बड़ी संख्या का समर्थन करती हैं, जैसे () नक्शा और () कम करते हैं , और न केवल। आप Rivertrail के लिए विनिर्देशन में पूरी सूची पा सकते हैं। ये विधियाँ तर्कों के रूप में कार्य करती हैं, और नियमित जेएस सरणियों में संबंधित कार्यों के समान कार्य करती हैं। कुछ महत्वपूर्ण अंतरों के अलावा:
  • सबसे पहले, जिन कार्यों को एक तर्क के रूप में लिया जाता है, उन्हें हमेशा "शुद्ध" होना चाहिए, उस पर अधिक;
  • दूसरी बात, जहाँ संभव हो, JS इंजन समानांतर में इन कार्यों को करने की कोशिश करेगा।

शुद्ध कार्य
ये साधारण जेएस फ़ंक्शन हैं जो साझा स्थिति को नहीं बदलते हैं। इसका मतलब यह नहीं है कि फ़ंक्शन कुछ भी नहीं बदल सकते हैं - फ़ंक्शन द्वारा आवंटित स्थानीय चर और ऑब्जेक्ट ही बदल सकते हैं।

उदाहरण के लिए, मैंडलब्रॉट सेट की गणना करने वाला एक फ़ंक्शन शुद्ध है:

function mandelbrot(x, y) { var Cr = (x - 256) / scale + 0.407476; var Ci = (y - 256) / scale + 0.234204; var I = 0, R = 0, I2 = 0, R2 = 0; var n = 0; while ((R2+I2 < 2.0) && (n < 512)) { I = (R+R)*I+Ci; R = R2-I2+Cr; R2 = R*R; I2 = I*I; n++; } return n; } 

mandelbrot () केवल स्थानीय चर को संशोधित करता है। लेकिन इस संबंध में रकम () अधिक दिलचस्प है - फ़ंक्शन इनपुट एक्स के आंशिक रकम की गणना करता है और उन्हें आउटपुट सरणी रकम में संग्रहीत करता है:

 function sums(x) { var sums = [], sum = 0; for (var i = 0; i < x.length; i++) { sum += x[i]; sums[i] = sum; } return sums; } 

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

और यहां एक फ़ंक्शन का एक उदाहरण है जिसे शुद्ध नहीं माना जाएगा, क्योंकि यह एक्स को बदलता है, और एक्स स्थानीय रूप से आवंटित नहीं किया गया है।

 x = [1, 2, 3]; function impure() { x[0] += 1; } 

समानांतर निष्पादन
ParallelArray का मुख्य जादू यह है कि जहां तक ​​संभव हो, यह समानांतर में कार्य करेगा। इस मामले में, समानता या निष्पादन का क्रम जेएस के कार्यान्वयन पर निर्भर करेगा। तथ्य यह है कि समानांतर निष्पादन के लिए कार्य करने वाले उद्देश्य शुद्ध हैं, वैचारिक रूप से उन्हें हमेशा सुरक्षित रूप से निष्पादित किया जा सकता है। लेकिन इसका मतलब यह नहीं है कि जेएस इंजन खुद उन्हें निष्पादित करने में सक्षम होगा।

जेएस इंजन बहुत सारे गुप्त अनुकूलन करते हैं, और ये सभी अनुकूलन थ्रेड-सुरक्षित नहीं हैं।

अब तक, समानांतर में किए गए संचालन की सूची रूढ़िवादी है, लेकिन समय के साथ इसका विस्तार होगा और, आदर्श रूप से, विस्तार होगा ताकि कोई भी शुद्ध कार्य समानांतर में किया जा सके।

आपका कोड तेज़ है यह सुनिश्चित करने के लिए आपको कई काम करने होंगे। समानांतर कोड निष्पादन सुनिश्चित करने के लिए, आपको वही चीजें करनी होंगी। यही कारण है कि

उदाहरण

 ab = c 

यदि जेआईटी कंपाइलर एक प्रकार का विश्लेषण करता है और निर्धारित करता है, उदाहरण के लिए, संपत्ति बी हमेशा एक निश्चित ऑफसेट के साथ संग्रहीत होती है, तो यह कोड को एक एकल कोडांतरक अनुदेश में अनुकूलित करने में सक्षम होगा। लेकिन अगर संकलक कोड को पार्स करने में विफल रहता है, तो सबसे खराब स्थिति में, दुभाषिया को बुलाया जाएगा, जो विभिन्न हैश टेबल पर काम कर रहा है, पेड़ों को प्रोटोटाइप कर रहा है, और इसी तरह। अब आपको यह समझने की ज़रूरत है कि ab = c थ्रेड सुरक्षित है। यहां सब कुछ सरल है - यह बचाने का निर्देश इस धारणा के तहत सुरक्षित है कि केवल एक थ्रेड में मेमोरी तक पहुंच होती है जिसमें इसे बचाया जाता है। जो फ़ंक्शन की "शुद्धता" की गारंटी है। इसे हल करना अधिक कठिन होगा जब दुभाषिया सैकड़ों को छूता है, यदि हजारों नहीं, तो कोड की लाइनें।

बेशक, यह जानना कि कौन सा कोड प्रभावी रूप से संकलित किया जाएगा, एक जीत नहीं है। निम्नलिखित लेखों में मैं कुछ चीजों के बारे में बात करूंगा जो आज के लिए समानांतर निष्पादन सुनिश्चित करते हैं, और भविष्य के लिए इस क्षेत्र में कुछ पूर्वानुमान देते हैं।

समानांतर निष्पादन मॉडल
Rivertrail Mozill का उपयोग मॉडल Intel के प्रोटोटाइप से थोड़ा अलग है। यह OpenCL में JS को संकलित करने वाला एक प्लगइन है। मूल कार्यान्वयन आपको कोड को 4 अलग-अलग तरीकों से निष्पादित करने की अनुमति देता है, लेकिन फिलहाल केवल पहले 2 उपलब्ध हैं।

  • क्रमिक रूप से । स्टैंडबाय मोड। लूप के लिए लिखने या उच्च-स्तरीय सरणी विधियों का उपयोग करने के लिए बराबर। यह मोड ऑरोरा में नाइटली बिल्ड और संभवतः काम करता है। कंसोल में var x = new ParallelArray ([1, 2, 3] टाइप करने का प्रयास करें
  • मल्टीकोर मोड । इस मोड में, और डिफ़ॉल्ट रूप से काम करते हैं। मल्टी-कोर मोड सिस्टम में प्रति कोर एक धागा वितरित करता है। प्रत्येक कार्यकर्ता थ्रेड फ़ंक्शन की समानांतर प्रतिलिपि के साथ काम करेगा। हम अगले कुछ महीनों में इस मोड के अधिक कार्यात्मक संस्करण की उम्मीद करते हैं।
  • सदिश मोड। यह मल्टी-कोर एक जैसा दिखता है, लेकिन इसमें अंतर हैं - प्रत्येक कार्यकर्ता थ्रेड एक समय में एक से अधिक सरणी तत्व को संसाधित करने के लिए एसएसई निर्देशों का उपयोग करता है। मल्टीकोर के बाद की योजनाओं में यह अभी भी है।
  • GPU। यह वेक्टराइजेशन मोड का केवल एक संस्करण है, लेकिन इसमें कोड का वेक्टरकरण सीपीयू पर नहीं, बल्कि जीपीयू पर काम करेगा। कई तकनीकी अंतर हैं। एक ओर, वेक्टरकरण को हार्डवेयर में GPU द्वारा नियंत्रित किया जाएगा, और संकलक को विशेष निर्देशों का उपयोग नहीं करना होगा। दूसरी ओर, कुछ प्लेटफार्मों पर आपको सीपीयू और जीपीयू के बीच मेमोरी कॉपी करने के लिए कड़ी मेहनत करनी होगी।

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

वेक्टरकरण और GPU मोड अधिक सीमित होंगे। यह केवल उन कार्यों के लिए वेक्टरकरण का उपयोग करने के लिए समझ में आएगा जिसमें कोड को पैकिंग और अनपैकिंग के बिना SSE निर्देशों में परिवर्तित किया जा सकता है, जबकि GPU डेटा के आंदोलन पर कुछ प्रतिबंध लगाएगा, और इसी तरह।

प्रदर्शन के बारे में कुछ शब्द
चूंकि कुछ डेटा होगा
  • मैंने अभी तक रूपरेखा तैयार नहीं की है
  • कोई अच्छा विस्तृत परीक्षण अभी तक नहीं
  • गणना का अनुकूलन भी विफल रहा

कम से कम, यहां हाइपरथिएडिंग के साथ मेरे क्वाड-कोर लैपटॉप पर सेट मैंडेलब्रोट की गणना के परिणाम हैं।

seq - क्रमिक मोड में रनटाइम
समानांतर मोड में समान थ्रेड्स के बराबर रनटाइम
अनुपात - अनुक्रमिक मोड के समय का अनुपात समानांतर (seq / par) के समय तक। अधिक, बेहतर है।
धागेSeq (ms)Par (एमएस)अनुपात (Seq / Par)
1297625151.18
2295217821.65
4296414172.09
8288011492.50
16289111092.60
जाहिर है, इन मूल्यों में सुधार किया जा सकता है। यह बहुत अच्छा होगा अगर उत्पादकता रैखिक रूप से बढ़ेगी। और मुझे नहीं लगता कि यह हासिल करना मुश्किल है, मैं आशावादी हूं।

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

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

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

अनुवाद और संपादन में मेरी मदद करने के लिए vikky13 का धन्यवाद।

Source: https://habr.com/ru/post/In154999/


All Articles