2012-09-21 20 views
15

मेरे पास हैकेल की समझ में काफी कुछ है, लेकिन मुझे हमेशा इस बारे में बहुत अनिश्चितता है कि मुझे किस तरह के प्रागमा और अनुकूलन का उपयोग करना चाहिए और कहां जाना चाहिए।विभिन्न भाषा प्रागमाओं और अनुकूलन का उपयोग कब करें?

  • SPECIALIZE प्रगामा का उपयोग कब करें और इसका प्रदर्शन लाभ क्या है।
  • RULES का उपयोग कहां करें। मैंने लोगों को एक विशेष नियम लेने के बारे में सुना है जो फायरिंग नहीं कर रहे हैं? हम इसे कैसे देख सकते हैं?
  • किसी फ़ंक्शन के तर्क कब सख्त करना है और यह कब मदद करता है? मैं समझता हूं कि तर्क को सख्त बनाने से तर्कों को सामान्य रूप में मूल्यांकन किया जाएगा, तो मुझे सभी फ़ंक्शन तर्कों के लिए सख्तता क्यों नहीं जोड़नी चाहिए? मैं कैसे तय करूं?
  • मैं कैसे देख सकता हूं और जांच सकता हूं कि मेरे पास मेरे प्रोग्राम में स्पेस लीक है? एक सामान्य रिसाव क्या है जो एक अंतरिक्ष रिसाव के लिए गठन कर रहे हैं?
  • मैं कैसे देख सकता हूं कि बहुत आलसीपन में कोई समस्या है या नहीं? मैं हमेशा ढेर प्रोफाइलिंग की जांच कर सकता हूं लेकिन मैं जानना चाहता हूं कि सामान्य कारण, उदाहरण और पैटर्न क्या हैं जहां आलस्य दर्द होता है?

क्या कोई स्रोत है जो उन्नत अनुकूलन (उच्च और बहुत कम स्तर पर दोनों) के बारे में बात करता है, विशेष रूप से विशेष रूप से विशेष रूप से हैकेल?

+0

आरएचडब्ल्यू सी 25? http://book.realworldhaskell.org/read/profiling-and-optimization.html –

+0

@ डॉनस्टवार्ट धन्यवाद .. मैंने पहले से ही आरडब्ल्यूएच पढ़ा है .. समस्या यह है कि मुझे पता है कि वे क्या करते हैं लेकिन मेरे पास कोई अंतर्ज्ञान नहीं है और जहां उनका उपयोग महत्वपूर्ण है और महत्वपूर्ण नहीं है। मैंने इस प्रश्न से मेरी समझ को और बढ़ाने के लिए अन्य स्रोतों को खोजने के लिए कहा। – Satvik

उत्तर

18

SPECIALIZE प्रगामा का उपयोग कब करें और इसका प्रदर्शन लाभ क्या है।

आप संकलक एक समारोह विशेषज्ञ यदि आप एक (प्रकार वर्ग) बहुरूपी समारोह है, और उम्मीद है कि यह एक या वर्ग (ते) के कुछ उदाहरणों में अक्सर के नाम से जाना करते हैं।

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

जीएचसी -7 के रूप में, यह संभवतः {-# INLINABLE #-} प्रगामा को देने के लिए अधिक उपयोगी है, जो इंटरफ़ेस फ़ाइल में उपलब्ध (लगभग अपरिवर्तित, कुछ सामान्यीकृत और desugaring किया जाता है) स्रोत बनाता है, इसलिए फ़ंक्शन विशिष्ट हो सकता है और संभावित रूप से कॉल साइट पर भी रेखांकित।

RULES का उपयोग कहां करें। मैंने लोगों को एक विशेष नियम लेने के बारे में सुना है जो फायरिंग नहीं कर रहे हैं? हम इसे कैसे देख सकते हैं?

आप देख सकते हैं कि -ddump-rule-firings कमांड लाइन विकल्प का उपयोग करके आप कौन से नियम निकाल चुके हैं। यह आमतौर पर बड़ी संख्या में निकाल दिए गए नियमों को डंप करता है, इसलिए आपको अपने नियमों के लिए थोड़ा सा खोजना होगा।

आप का उपयोग नियम

  • आप विशेष प्रकार, उदाहरण के लिए एक समारोह के एक अधिक कुशल संस्करण है जब

    {-# RULES 
    "realToFrac/Float->Double" realToFrac = float2Double 
        #-} 
    
  • जब कुछ कार्यों विशेष तर्क है, उदा के लिए एक अधिक कुशल संस्करण के साथ प्रतिस्थापित किया जा सकता है

    {-# RULES 
    "^2/Int"  forall x. x^(2 :: Int) = let u = x in u*u 
    "^3/Int"  forall x. x^(3 :: Int) = let u = x in u*u*u 
    "^4/Int"  forall x. x^(4 :: Int) = let u = x in u*u*u*u 
    "^5/Int"  forall x. x^(5 :: Int) = let u = x in u*u*u*u*u 
    "^2/Integer" forall x. x^(2 :: Integer) = let u = x in u*u 
    "^3/Integer" forall x. x^(3 :: Integer) = let u = x in u*u*u 
    "^4/Integer" forall x. x^(4 :: Integer) = let u = x in u*u*u*u 
    "^5/Integer" forall x. x^(5 :: Integer) = let u = x in u*u*u*u*u 
        #-} 
    
  • जब सामान्य कानूनों के अनुसार अभिव्यक्ति को फिर से लिखना कोड उत्पन्न हो सकता है जो अनुकूलित करने के लिए बेहतर है, उदा।

    {-# RULES 
    "map/map" forall f g. (map f) . (map g) = map (f . g) 
        #-} 
    
उत्तरार्द्ध शैली में RULES की

व्यापक उपयोग base में सूची कार्यों के लिए text पुस्तकालय में, संलयन चौखटे में किया जाता है, उदाहरण के लिए, और, संलयन (foldr/build संलयन) एक अलग तरह कार्यान्वित किया जाता है नियमों का उपयोग करना

किसी फ़ंक्शन के तर्क कब सख्त करना है और यह कब मदद करता है? मैं समझता हूं कि तर्क को सख्त बनाने से तर्कों को सामान्य रूप में मूल्यांकन किया जाएगा, तो मुझे सभी फ़ंक्शन तर्कों के लिए सख्तता क्यों नहीं जोड़नी चाहिए? मैं कैसे तय करूं?

एक तर्क सख्त यह सुनिश्चित करेंगे कि यह, कमजोर सिर सामान्य रूप लिए मूल्यांकन किया जाता है सामान्य रूप के लिए नहीं बनाना।

आप सभी तर्कों को सख्त नहीं बनाते हैं क्योंकि कुछ कार्यों को उनके कुछ तर्कों में गैर-सख्त होना चाहिए और कुछ तर्कों में सख्त होने पर कुछ कम कुशल हैं।

examplepartition अनंत सूची में सब पर काम करने के लिए अपनी दूसरी बहस में गैर सख्त होना चाहिए के लिए, अधिक सामान्य हर foldr में इस्तेमाल किया दूसरा तर्क में गैर सख्त होना चाहिए समारोह अनंत सूची पर काम करने के लिए। सीमित सूचियों पर, दूसरे तर्क में फ़ंक्शन गैर-सख्त होने से यह नाटकीय रूप से अधिक कुशल हो सकता है (foldr (&&) True (False:replicate (10^9) True))।

यदि आप जानते हैं कि किसी भी सार्थक काम को वैसे भी किया जा सकता है, तो तर्क का मूल्यांकन किया जाना चाहिए। कई मामलों में, जीएचसी का सख्तता विश्लेषक स्वयं ही ऐसा कर सकता है, लेकिन बिल्कुल नहीं।

एक बहुत ही सामान्य मामला लूप या पूंछ के रिकर्सन में जमाकर्ता होते हैं, जहां सख्तता जोड़ने से रास्ते में भारी मात्रा में निर्माण होता है।

मुझे सख्तता जोड़ने के लिए कोई कठोर और तेज़ नियम नहीं पता है, मेरे लिए यह अनुभव की बात है, थोड़ी देर के बाद आप सीखते हैं कि सख्तता में कौन सी जगहें मदद करने की संभावना है और कहां नुकसान पहुंचा सकता है।

अंगूठे के नियम के रूप में, छोटे डेटा (जैसे Int) का मूल्यांकन करना समझ में आता है, लेकिन अपवाद हैं।

मैं कैसे देख सकता हूं और जांचता हूं कि मेरे पास मेरे प्रोग्राम में एक स्थान रिसाव है? एक सामान्य रिसाव क्या है जो एक अंतरिक्ष रिसाव के लिए गठन कर रहे हैं?

पहला चरण +RTS -s विकल्प का उपयोग करना है (यदि प्रोग्राम rtsopts सक्षम से जुड़ा हुआ था)। इससे आपको पता चलता है कि कुल मिलाकर कितनी मेमोरी का उपयोग किया जाता था, और आप अक्सर इसका फैसला कर सकते हैं कि क्या आपके पास रिसाव है या नहीं। +RTS -hT विकल्प के साथ प्रोग्राम चलाने से अधिक जानकारीपूर्ण आउटपुट प्राप्त किया जा सकता है, जो एक ढेर प्रोफ़ाइल उत्पन्न करता है जो अंतरिक्ष रिसाव को खोजने में मदद कर सकता है (साथ ही, कार्यक्रम को सक्षम rtsopts से जोड़ा जाना चाहिए)।

आगे के विश्लेषण की आवश्यकता है, कार्यक्रम की रूपरेखा को सक्षम करने पर संकलित किए जाने की आवश्यकता (पुराने GHCs में, -rtsops -prof -fprof-auto, -fprof-auto विकल्प उपलब्ध नहीं था, -prof-auto-all विकल्प करीबी पत्राचार है)।

फिर आप इसे विभिन्न प्रोफाइल विकल्पों के साथ चलाते हैं और जेनरेटेड हीप प्रोफाइल देखते हैं।

दो अंतरिक्ष लीक के लिए सबसे सामान्य कारणों में

  • बहुत ज्यादा आलस्य
  • थोड़ा आम उपसूचक उन्मूलन बहुत ज्यादा कड़ाई

तीसरे स्थान पर शायद अवांछित साझा करने से लिया जाता है, GHC करता हैं , लेकिन यह कभी-कभी जहां भी नहीं चाहता था, लंबी सूची सूचीबद्ध करता है।

रिसाव के कारण को खोजने के लिए, मुझे फिर से कोई कठोर और तेज़ नियम नहीं पता है, और कभी-कभी, एक स्थान पर सख्तता जोड़कर या किसी अन्य में आलस्य जोड़कर एक रिसाव तय किया जा सकता है।

मैं कैसे देख सकता हूं कि बहुत आलसीपन में कोई समस्या है या नहीं? मैं हमेशा ढेर प्रोफाइलिंग की जांच कर सकता हूं लेकिन मैं जानना चाहता हूं कि सामान्य कारण, उदाहरण और पैटर्न क्या हैं जहां आलस्य दर्द होता है?

आम तौर पर, आलस्य तलाश है जहां परिणाम संवर्द्धित का निर्माण किया जा सकता है, और अवांछित से पहले प्रक्रिया पूरी हो जाने, छोड़ दिया परतों में या आम तौर पर पूंछ पुनरावर्ती कार्यों में की तरह है, जहां परिणाम का कोई हिस्सा नहीं दिया जा सकता है।

+0

वास्तव में एक अच्छा जवाब के लिए धन्यवाद। – Satvik

3

मैं Pragmas और Rewrite Rules पर जीएचसी दस्तावेज पढ़ने की सलाह देता हूं, क्योंकि वे विशेषताओं और नियमों के बारे में आपके कई प्रश्नों को संबोधित करते हैं।

संक्षेप में अपने प्रश्नों के समाधान के लिए:

  • विशेषज्ञ एक विशेष प्रकार के लिए एक बहुरूपी समारोह की एक विशेष संस्करण बनाने के लिए संकलक मजबूर करने के लिए प्रयोग किया जाता है। लाभ यह है कि उस मामले में फ़ंक्शन को लागू करने के लिए अब शब्दकोश की आवश्यकता नहीं होगी। नुकसान यह है कि यह आपके कार्यक्रम के आकार में वृद्धि करेगा। विशेषज्ञता "आंतरिक-लूप" नामक कार्यों के लिए विशेष रूप से मूल्यवान है, और यह अनिवार्य रूप से निम्न स्तर के कार्यों के लिए बेकार है। इनलाइन के साथ इंटरैक्शन के लिए GHC documentation देखें।

  • नियम आपको उन नियमों को फिर से लिखने की अनुमति देता है जिन्हें आप वैध मानते हैं लेकिन संकलक स्वयं का अनुमान नहीं लगा सकता है। आम उदाहरण {-# RULES "mapfusion" forall f g xs. map f (map g xs) = map (f.g) xs #-} है, जो जीएचसी को map को फ्यूज करने का तरीका बताता है। इनलाइन के साथ हस्तक्षेप के कारण जीएचसी नियमों का उपयोग करना मुश्किल हो सकता है। 7.19.3 टकराव से बचने के तरीके और जीएचसी को नियम का उपयोग करने के लिए मजबूर करने के तरीके को कैसे छूता है, भले ही यह सामान्य रूप से इससे बचें।

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

  • मेरा अनुभव यह रहा है कि अधिकांश शो-स्टॉपिंग स्पेस लीक आलसी जमाकर्ताओं और अनावश्यक आलसी मूल्यों से बहुत बड़े डेटा-संरचनाओं में आये हैं, हालांकि मुझे यकीन है कि यह आपके द्वारा लिखे जाने वाले कार्यक्रमों के लिए विशिष्ट है। जब भी संभव हो तो अनबॉक्स किए गए डेटा-स्ट्रक्चर का उपयोग करना बहुत सारी समस्याओं को हल करता है।

  • उन उदाहरणों के बाहर जहां आलस्य अंतरिक्ष-रिसाव का कारण बनता है, प्रमुख स्थिति जहां इसे टालना चाहिए IO में होना चाहिए। आलसी प्रसंस्करण संसाधन संसाधन की आवश्यकता होने पर वॉल-घड़ी के समय की मात्रा को मूल रूप से बढ़ाता है। यह कैश प्रदर्शन के लिए खराब हो सकता है, और यह स्पष्ट रूप से खराब है अगर कुछ अन्य संसाधनों का उपयोग करने के अनन्य अधिकार चाहते हैं।