डाइनैमिक एक्ज़ीक्यूशन

समस्या की शिकायत करें सोर्स देखें

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

इस पेज पर डाइनैमिक एक्ज़ीक्यूशन को चालू करने, ट्यून करने, और डीबग करने का तरीका बताया गया है. अगर आपने लोकल और रिमोट, दोनों तरह के एक्ज़ीक्यूशन सेट अप किए हैं और बेहतर परफ़ॉर्मेंस के लिए, Basel की सेटिंग में बदलाव करना है, तो यह पेज आपके लिए है. अगर आपने पहले से रिमोट तरीके से एक्ज़ीक्यूशन की सुविधा सेट अप नहीं की है, तो सबसे पहले Basel Remote exeution Overview पर जाएं.

डाइनैमिक एक्ज़ीक्यूशन चालू हो रहा है?

डाइनैमिक एक्ज़ीक्यूशन मॉड्यूल बेज़ल का हिस्सा है, लेकिन डाइनैमिक एक्ज़ीक्यूशन का इस्तेमाल करने के लिए, आपको एक ही बेज़ल सेटअप से, लोकल और रिमोट, दोनों तरीकों से कंपाइल करने की सुविधा पहले से ही मिलनी चाहिए.

डाइनैमिक एक्ज़ीक्यूशन मॉड्यूल को चालू करने के लिए, --internal_spawn_scheduler फ़्लैग को Bagel को पास करें. ऐसा करने पर, प्लान लागू करने की नई रणनीति जुड़ जाती है, जिसका नाम dynamic है. अब इसका इस्तेमाल उन चीज़ों के लिए रणनीति के तौर पर किया जा सकता है जिन्हें आपको डाइनैमिक तरीके से चलाना है, जैसे कि --strategy=Javac=dynamic. अगले सेक्शन में जाकर यह चुनने का तरीका जानें कि यादगार चीज़ों के लिए, डाइनैमिक तरीके से एक्ज़ीक्यूट करने की सुविधा चालू करनी है.

डाइनैमिक रणनीति का इस्तेमाल करने वाली किसी भी याद के लिए, रिमोट तरीके से लागू करने की रणनीतियों को --dynamic_remote_strategy फ़्लैग से और स्थानीय रणनीतियों को --dynamic_local_strategy फ़्लैग से लिया जाता है. पासिंग --dynamic_local_strategy=worker,sandboxed, डाइनैमिक एक्ज़ीक्यूशन की लोकल ब्रांच के लिए डिफ़ॉल्ट तौर पर सेट हो जाती है, ताकि उस ऑर्डर में वर्कर या सैंडबॉक्स की गई एक्ज़ीक्यूशन के साथ कोशिश की जा सके. --dynamic_local_strategy=Javac=worker को पास करना, सिर्फ़ Javac मेनेमोनिक के लिए डिफ़ॉल्ट सेटिंग को ओवरराइड करता है. रिमोट वर्शन इसी तरह से काम करता है. दोनों फ़्लैग एक से ज़्यादा बार तय किए जा सकते हैं. अगर किसी कार्रवाई को स्थानीय तौर पर लागू नहीं किया जा सकता है, तो उसे रिमोट तरीके से सामान्य तरीके से और दूसरी जगह से लागू किया जाता है.

अगर आपके रिमोट सिस्टम में कोई कैश मेमोरी है, तो --dynamic_local_execution_delay फ़्लैग कैश मेमोरी में सेव होने वाले हिट का संकेत देने के बाद, लोकल एक्ज़ीक्यूशन में मिलीसेकंड में देरी जोड़ता है. इससे, ज़्यादा कैश मेमोरी हिट होने की संभावना होने पर लोकल एक्ज़ीक्यूशन नहीं चलता. डिफ़ॉल्ट वैल्यू 1000 मि॰से॰ है. हालांकि, इसे इस तरह से सेट किया जाना चाहिए कि आम तौर पर कैश मेमोरी से मिलने वाले हिट से थोड़ा ज़्यादा समय लगता है. वास्तविक समय रिमोट सिस्टम पर और दोतरफ़ा यात्रा में लगने वाला समय, दोनों पर निर्भर करता है. आम तौर पर, किसी रिमोट सिस्टम का इस्तेमाल करने वाले सभी लोगों के लिए वैल्यू एक जैसी रहेगी. हालांकि, ऐसा तब तक होगा, जब तक उनमें से कुछ उपयोगकर्ता, दोतरफ़ा यात्रा का समय जोड़ने के लिए काफ़ी न हों. Basel प्रोफ़ाइलिंग की सुविधाएं इस्तेमाल करके, यह देखा जा सकता है कि आम तौर पर कैश मेमोरी में सेव होने वाले हिट में कितना समय लगता है.

डाइनैमिक एक्ज़ीक्यूशन का इस्तेमाल, लोकल सैंडबॉक्स वाली रणनीति के साथ-साथ परसिस्टेंट वर्कर के साथ भी किया जा सकता है. डाइनैमिक एक्ज़ीक्यूशन के साथ इस्तेमाल किए जाने पर, स्थायी वर्कर अपने-आप सैंडबॉक्स की सुविधा से चलेंगे और मल्टीप्लेक्स वर्कर का इस्तेमाल नहीं कर पाएंगे. डार्विन और Windows सिस्टम पर, सैंडबॉक्स की गई रणनीति धीमी हो सकती है. इन सिस्टम पर सैंडबॉक्स बनाने के काम को कम करने के लिए, --reuse_sandbox_directories को पास किया जा सकता है.

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

अगर डाइनैमिक एक्ज़ीक्यूशन की कोई एक ब्रांच पहले पूरी हो जाती है, लेकिन वह पूरी नहीं हो पाती है, तो पूरी कार्रवाई नहीं हो पाती. यह फ़ैसला सोच-समझकर लिया गया है, ताकि लोकल और ऑफ़िस से दूर रहकर काम करने की सुविधा के बीच के अंतर को किसी की नज़र न आए.

डाइनैमिक एक्ज़ीक्यूशन और लॉक करने की सुविधा के काम करने के तरीके के बारे में ज़्यादा जानने के लिए, जूलियो मेरिनो की शानदार ब्लॉग पोस्ट देखें.

मुझे डाइनैमिक एक्ज़ीक्यूशन का इस्तेमाल कब करना चाहिए?

डाइनैमिक एक्ज़ीक्यूशन के लिए, किसी भी तरह के रिमोट एक्ज़ीक्यूशन सिस्टम की ज़रूरत होती है. फ़िलहाल, सिर्फ़ कैश मेमोरी में सेव किए गए रिमोट सिस्टम का इस्तेमाल नहीं किया जा सकता, क्योंकि कैश मेमोरी में सेव न होने पर, इसे फ़ेल माना जाएगा.

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

5.0.0-pre.20210708.4 रिलीज़ के बाद से, परफ़ॉर्मेंस प्रोफ़ाइलिंग में कर्मचारियों के काम करने से जुड़ा डेटा शामिल है. इसमें डाइनैमिक एक्ज़ीक्यूशन के दौरान, कर्मचारियों के काम को करने से जुड़ा डेटा भी शामिल है. अगर आपको डाइनैमिक एक्ज़ीक्यूशन वर्कर थ्रेड संसाधनों को पाने में काफ़ी समय या async-worker-finish में बहुत ज़्यादा समय खर्च होता हुआ दिखता है, तो हो सकता है कि वर्कर थ्रेड में देरी हो रही हो.

डाइनैमिक एक्ज़ीक्यूशन की परफ़ॉर्मेंस खराब होने पर, डेटा की प्रोफ़ाइल बनाना

ऊपर दी गई प्रोफ़ाइल में, जो 8 Javac वर्कर का इस्तेमाल करती है, हमने देखा है कि कई Javac वर्कर ने async-worker-finish थ्रेड पर अपनी रेस हार गई हैं और अपना काम पूरा किया है. ऐसा इसलिए हुआ, क्योंकि काम न करने वाले लोगों को याद करने के लिए ज़रूरी संसाधन ले जाने थे और काम करने में देरी हुई.

बेहतर डाइनैमिक एक्ज़ीक्यूशन परफ़ॉर्मेंस के साथ डेटा को फ़िल्टर करना

जब सिर्फ़ Javac को डाइनैमिक एक्ज़ीक्यूशन के साथ चलाया जाता है, तो काम शुरू करने के बाद सिर्फ़ आधे कर्मचारी ही रेस में हारते हैं.

पहले सुझाए गए --experimental_spawn_scheduler फ़्लैग का इस्तेमाल नहीं किया जा सकता. यह डाइनैमिक एक्ज़ीक्यूशन को चालू करता है और dynamic को याद रखने की चीज़ों के लिए डिफ़ॉल्ट रणनीति के तौर पर सेट करता है. इससे इस तरह की समस्याएं अक्सर पैदा होती हैं.

परफ़ॉर्मेंस

डाइनैमिक एक्ज़ीक्यूशन के तरीके में यह माना जाता है कि लोकल और रिमोट लोकेशन के लिए ज़रूरत के मुताबिक संसाधन उपलब्ध हैं. पूरे परफ़ॉर्मेंस को बेहतर बनाने के लिए कुछ अतिरिक्त संसाधन खर्च किए जा सकते हैं. हालांकि, संसाधनों का बहुत ज़्यादा इस्तेमाल करने से, Basel या इस पर चलने वाली मशीन की स्पीड धीमी हो सकती है. इसके अलावा, रिमोट सिस्टम पर अनचाहा दबाव पड़ सकता है. डाइनैमिक एक्ज़ीक्यूशन का व्यवहार बदलने के लिए कई विकल्प हैं:

रिमोट ब्रांच के शुरू होने के बाद, --dynamic_local_execution_delay लोकल ब्रांच के शुरू होने की प्रोसेस में कुछ मिलीसेकंड तक देरी करता है. हालांकि, ऐसा सिर्फ़ तब होता है, जब मौजूदा बिल्ड के दौरान रिमोट कैश हिट हुआ हो. इससे ऐसे बिल्ड बन जाते हैं जो रिमोट कैश करने से फ़ायदा होता है. इससे लोकल संसाधनों की बर्बादी नहीं होती. ऐसा तब होता है, जब इस बात की संभावना ज़्यादा होती है कि ज़्यादातर आउटपुट कैश मेमोरी में मिल सकते हैं. कैश मेमोरी की क्वालिटी के आधार पर, इसमें कमी करने से बिल्ड की स्पीड बेहतर हो सकती है. हालांकि, इसके लिए ज़्यादा स्थानीय संसाधनों का इस्तेमाल करना पड़ता है.

--experimental_dynamic_local_load_factor, संसाधन को मैनेज करने का बेहतर विकल्प है. फ़िलहाल, इसे आज़माया जा रहा है. इस सुविधा को बंद करने के लिए, इसकी वैल्यू 0 से 1 के बीच होनी चाहिए. अगर गेम को 0 से ज़्यादा की वैल्यू पर सेट किया जाता है, तो आस-पास की जाने वाली कई कार्रवाइयों को शेड्यूल करने के दौरान, Basel की मदद से शेड्यूल की गई कार्रवाइयों की संख्या में बदलाव किया जाता है. इसे 1 पर सेट करने पर, --local_cpu_resources के मुताबिक, सीपीयू की सुविधा उपलब्ध होने पर कई कार्रवाइयां शेड्यूल की जा सकती हैं. कम वैल्यू से, शेड्यूल की गई कार्रवाइयों की संख्या उसी हिसाब से कम सेट हो जाती है. ऐसा इसलिए होता है, क्योंकि ज़्यादा संख्या में कार्रवाइयां करने के लिए उपलब्ध होती हैं. यह थोड़ा मुश्किल लग सकता है, लेकिन एक अच्छे रिमोट सिस्टम के साथ, जब कई कार्रवाइयां चल रही होती हैं, तो लोकल सीपीयू के इस्तेमाल से ज़्यादा मदद नहीं मिलती. साथ ही, रिमोट ऐक्शन को मैनेज करने में लोकल सीपीयू बेहतर तरीके से खर्च होता है.

जब रिमोट ब्रांच कम से कम इतने समय से चल रही हो, तो --experimental_dynamic_slow_remote_time लोकल ब्रांच को शुरू करने को प्राथमिकता देता है. आम तौर पर, हाल ही में शेड्यूल की गई कार्रवाई को प्राथमिकता दी जाती है, क्योंकि इसमें रेस जीतने की संभावना सबसे ज़्यादा होती है. हालांकि, अगर रिमोट सिस्टम कभी-कभी रुक जाता है या ज़्यादा ज़्यादा समय लग जाता है, तो इससे आगे बढ़ने में मदद मिलती है. यह सुविधा डिफ़ॉल्ट रूप से चालू नहीं होती, क्योंकि इससे रिमोट सिस्टम से जुड़ी समस्याएं हो सकती हैं. इन्हें ठीक करना ज़रूरी होता है. अगर आपने इस विकल्प को चालू किया है, तो अपने रिमोट सिस्टम की परफ़ॉर्मेंस पर नज़र रखना न भूलें.

अगर दिए गए सिग्नल की वजह से स्थानीय स्पॉन्स बाहर निकलता है, तो रिमोट ब्रांच को टेकओवर करने के लिए, --experimental_dynamic_ignore_local_signals का इस्तेमाल किया जा सकता है. यह मुख्य तौर पर, वर्कर रिसॉर्स की सीमाओं (--experimental_worker_memory_limit_mb, --experimental_worker_sandbox_hardening, और --experimental_sandbox_memory_limit_mb) की मदद से एक साथ काम करता है. ज़्यादा संसाधनों का इस्तेमाल करने पर, वर्कर प्रोसेस खत्म हो सकती हैं.

JSON ट्रेस प्रोफ़ाइल में परफ़ॉर्मेंस से जुड़े कई ग्राफ़ शामिल होते हैं जो परफ़ॉर्मेंस और संसाधन के इस्तेमाल के व्यापार को बेहतर बनाने के तरीकों की पहचान करने में मदद कर सकते हैं.

समस्या हल करना

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

अगर आपको standalone रणनीति का इस्तेमाल करके डाइनैमिक एक्ज़ीक्यूशन में समस्याएं आ रही हैं, तो --experimental_local_lockfree_output के बिना दौड़ने की कोशिश करें या सैंडबॉक्स की गई अपनी लोकल ऐक्शन को चलाएं. यह आपके बिल्ड को धीमा कर सकता है (ऊपर देखें कि क्या आप Mac या Windows पर हैं), लेकिन इसके विफल होने की कुछ संभावित वजहें भी हट जाती हैं.