अंतिम उपाय [बंद] का प्रदर्शन अनुकूलन रणनीति


609

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

चलो मान लो:

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

मैं यहाँ जो देख रहा हूँ वह एक महत्वपूर्ण एल्गोरिथ्म में अंतिम कुछ प्रतिशत तक निचोड़ने के लिए रणनीति और चालें हैं जब ऐसा करने के लिए और कुछ नहीं बचा है, लेकिन जो कुछ भी लेता है।

आदर्श रूप से, उत्तर भाषा को अज्ञेय बनाने की कोशिश करें, और जहां लागू हो, वहां सुझाई गई रणनीतियों के लिए किसी भी डाउन-साइड को इंगित करें।

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

जवाबों:


427

ठीक है, आप समस्या को परिभाषित कर रहे हैं जहां यह प्रतीत होता है कि सुधार के लिए बहुत जगह नहीं है। मेरे अनुभव में यह काफी दुर्लभ है। मैंने नवंबर 1993 में डॉ। डॉब्स लेख में इसे स्पष्ट करने की कोशिश की, जिसमें पारंपरिक रूप से अच्छी तरह से डिज़ाइन किए गए गैर-तुच्छ कार्यक्रम से शुरू हुआ, जिसमें कोई स्पष्ट अपशिष्ट नहीं था और इसे अनुकूलन की एक श्रृंखला के माध्यम से ले जाया गया जब तक कि इसकी दीवार-घड़ी का समय 48 सेकंड से कम नहीं हुआ। 1.1 सेकंड के लिए, और स्रोत कोड का आकार 4. के एक कारक से कम हो गया था। मेरा नैदानिक ​​उपकरण यह था । परिवर्तनों का क्रम यह था:

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

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

  • अब स्पष्ट अपराधियों को ढूंढना कठिन है, लेकिन कुछ छोटे हैं जिनके बारे में मैं कुछ कर सकता हूं, और समय 13 सेकंड तक चला जाता है।

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

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

  • उस रीडिज़ाइन को किया जाता है, जो स्रोत कोड को 4 के कारक से सिकोड़ता है, और समय 10 सेकंड तक कम हो जाता है।

अब, क्योंकि यह इतनी जल्दी हो रहा है, यह नमूना करना कठिन है, इसलिए मैं इसे करने के लिए 10 गुना अधिक काम देता हूं, लेकिन निम्नलिखित समय मूल कार्यभार पर आधारित हैं।

  • अधिक निदान से पता चलता है कि यह कतार-प्रबंधन में समय बिता रहा है। इन-लाइनिंग में 7 सेकंड का समय कम हो जाता है।

  • अब एक बड़ा समय लेने वाला नैदानिक ​​मुद्रण है जो मैं कर रहा था। फ्लश कि - 4 सेकंड।

  • अब सबसे बड़े टाइम-टेकर्स मॉलॉक और फ्री में कॉल करते हैं । ऑब्जेक्ट को रीसायकल - 2.6 सेकंड।

  • नमूना जारी रखते हुए, मुझे अभी भी ऐसे ऑपरेशन मिलते हैं जो कड़ाई से आवश्यक नहीं हैं - 1.1 सेकंड।

कुल गति कारक: 43.6

अब कोई भी दो कार्यक्रम एक जैसे नहीं हैं, लेकिन गैर-खिलौना सॉफ्टवेयर में मैंने हमेशा इस तरह की प्रगति देखी है। पहले आपको आसान सामान मिलता है, और फिर अधिक कठिन होता है, जब तक कि आप कम रिटर्न वाले बिंदु तक नहीं पहुंचते। तब आपके द्वारा हासिल की गई अंतर्दृष्टि अच्छी तरह से एक नया स्वरूप प्रदान कर सकती है, स्पीडअप के एक नए दौर की शुरुआत, जब तक आप फिर से कम रिटर्न नहीं मारते। अब इस बिंदु है जिस पर यह है कि क्या आश्चर्य का कोई मतलब हो सकता है ++iया i++या for(;;)या while(1)कर रहे हैं तेजी से: प्रकार के प्रश्नों के मैं स्टैक ओवरफ़्लो पर तो अक्सर देखते हैं।

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

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

जोड़ा: jerryjvl ने कुछ उदाहरणों का अनुरोध किया। यहाँ पहली समस्या है। इसमें कोड की अलग-अलग पंक्तियों की एक छोटी संख्या होती है, साथ में आधा समय लगता है:

 /* IF ALL TASKS DONE, SEND ITC_ACKOP, AND DELETE OP */
if (ptop->current_task >= ILST_LENGTH(ptop->tasklist){
. . .
/* FOR EACH OPERATION REQUEST */
for ( ptop = ILST_FIRST(oplist); ptop != NULL; ptop = ILST_NEXT(oplist, ptop)){
. . .
/* GET CURRENT TASK */
ptask = ILST_NTH(ptop->tasklist, ptop->current_task)

ये सूची क्लस्टर ILST (एक सूची वर्ग के समान) का उपयोग कर रहे थे। उन्हें सामान्य तरीके से लागू किया जाता है, जिसमें "सूचना छिपाना" का अर्थ है कि वर्ग के उपयोगकर्ताओं को परवाह नहीं थी कि उन्हें कैसे लागू किया गया है। जब इन पंक्तियों को लिखा गया था (लगभग 800 पंक्तियों की कोड में से) विचार इस विचार को नहीं दिया गया था कि ये एक "अड़चन" हो सकता है (मुझे उस शब्द से नफरत है)। वे बस चीजों को करने का अनुशंसित तरीका हैं। यह कहना आसान है कि इन बातों से बचना चाहिए था, लेकिन मेरे अनुभव में प्रदर्शन की सभी समस्याएं ऐसी हैं। सामान्य तौर पर, प्रदर्शन समस्याओं को बनाने से बचने की कोशिश करना अच्छा है। यह उन लोगों को खोजने और ठीक करने के लिए बेहतर है जो बनाए गए हैं, भले ही उन्हें "टाला जाना चाहिए" (दृष्टि में)।

यहाँ दो अलग लाइनों में दूसरी समस्या है:

 /* ADD TASK TO TASK LIST */
ILST_APPEND(ptop->tasklist, ptask)
. . .
/* ADD TRANSACTION TO TRANSACTION QUEUE */
ILST_APPEND(trnque, ptrn)

ये आइटम को उनके सिरों पर जोड़कर सूची बना रहे हैं। (फिक्स को सरणियों में आइटम एकत्र करना था, और एक ही बार में सभी सूचियों का निर्माण करना था।) दिलचस्प बात यह है कि ये कथन केवल लागत (यानी कॉल स्टैक पर) मूल समय के 3/48 थे, इसलिए वे अंदर नहीं थे वास्तव में शुरुआत में एक बड़ी समस्या । हालांकि, पहली समस्या को दूर करने के बाद, उन्होंने उस समय का 3/20 खर्च किया और इसलिए अब एक "बड़ी मछली" थी। सामान्य तौर पर, यह है कि यह कैसे जाता है।

मैं जोड़ सकता हूं कि यह परियोजना एक वास्तविक परियोजना से डिस्टिल्ड थी जिस पर मैंने मदद की थी। उस परियोजना में, प्रदर्शन की समस्याएं कहीं अधिक नाटकीय थीं (जैसे कि स्पीडअप थीं), जैसे कि किसी कार्य को पूरा करने के लिए आंतरिक लूप के भीतर डेटाबेस-एक्सेस रूटीन को कॉल करना।

संदर्भ जोड़ा: स्रोत कोड, दोनों मूल और पुन: डिज़ाइन, www.ddj.com में , 1993 के लिए, फ़ाइल 9311.zip में, फ़ाइल slug.asc और slug.zip में पाया जा सकता है ।

EDIT 2011/11/26: विजुअल C ++ में स्रोत कोड युक्त एक SourceForge प्रोजेक्ट है और इसे कैसे ट्यून किया गया था, इसका ब्लो-बाय-ब्लो विवरण है। यह केवल ऊपर वर्णित परिदृश्य के पहले आधे हिस्से से गुजरता है, और यह ठीक उसी क्रम का पालन नहीं करता है, लेकिन फिर भी मैग्नेट स्पीडअप का 2-3 ऑर्डर मिलता है।


3
मुझे आपके द्वारा ऊपर उल्लिखित चरणों के कुछ विवरण पढ़ने में अच्छा लगेगा। क्या स्वाद के लिए अनुकूलन के कुछ टुकड़ों को शामिल करना संभव है? (पोस्ट को बहुत लंबा किए बिना?)
jerryjvl

8
... मैंने एक पुस्तक भी लिखी है जो अब प्रिंट आउट है, इसलिए यह अमेज़ॅन पर एक हास्यास्पद कीमत के लिए जा रहा है - "बिल्डिंग बेहतर अनुप्रयोग" आईएसबीएन 0442017405। अनिवार्य रूप से एक ही सामग्री पहले अध्याय में है।
माइक डनलैवी

3
@ माइक डनलैवी, मैं आपको Google को यह बताने का सुझाव दूंगा कि आपने इसे पहले ही स्कैन कर लिया है। उनका शायद पहले से ही एक समझौता है जिसने भी आपके प्रकाशक को खरीदा है।
थोरबजोरन राव एंडरसन

19
@ Thorbjørn: बस फॉलो करने के लिए, मैंने GoogleBooks के साथ हुक अप किया, सभी फॉर्म भरे, और उन्हें एक हार्ड कॉपी भेजी। मुझे एक ईमेल वापस मिला जिसमें पूछा गया कि क्या मैं वास्तव में कॉपीराइट का मालिक हूं। प्रकाशक वैन नॉस्ट्रैंड रेनहोल्ड, जिसे इंटरनेशनल थॉम्पसन द्वारा खरीदा गया था, जिसे रॉयटर्स ने खरीदा था, और जब मैं उन्हें कॉल करने या ईमेल करने की कोशिश करता हूं तो यह एक ब्लैक होल की तरह होता है। तो यह सीमित है - मैं अभी तक इसे वास्तव में नीचे का पीछा करने के लिए ऊर्जा नहीं थी।
माइक डनलैवी

5
Google पुस्तकें लिंक: books.google.dk/books?id=8A43E1UFs_YC
Thorbjørn Ravn Andersen

188

सुझाव:

  • पुनः गणना के बजाय पूर्व-गणना करें : किसी भी लूप या बार-बार कॉल जिसमें गणना होती है जिसमें अपेक्षाकृत सीमित मात्रा में इनपुट होते हैं, एक लुकअप (सरणी या शब्दकोश) बनाने पर विचार करते हैं जिसमें मान्य श्रेणी में सभी मानों के लिए उस गणना का परिणाम होता है। आदानों। इसके बजाय एल्गोरिथ्म के अंदर एक साधारण लुकअप का उपयोग करें।
    डाउन-साइड्स : यदि कुछ पूर्व-संकलित मानों का वास्तव में उपयोग किया जाता है, तो इससे मामले और बदतर हो सकते हैं, साथ ही लुकअप महत्वपूर्ण मेमोरी ले सकता है।
  • पुस्तकालय विधियों का उपयोग न करें : अधिकांश पुस्तकालयों को परिदृश्यों की एक विस्तृत श्रृंखला के तहत सही ढंग से संचालित करने के लिए लिखे जाने की आवश्यकता होती है, और मापदंडों पर शून्य जांच करते हैं, आदि। एक विधि को फिर से लागू करने से आप बहुत सारे तर्क छीनने में सक्षम हो सकते हैं। आपके द्वारा उपयोग किए जा रहे सटीक परिस्थिति में लागू नहीं होता है।
    डाउन-साइड : अतिरिक्त कोड लिखने का मतलब बग के लिए अधिक सतह क्षेत्र है।
  • पुस्तकालय विधियों का उपयोग करें : अपने आप को विरोधाभास करने के लिए, भाषा पुस्तकालयों को उन लोगों द्वारा लिखा जाता है जो आपके या मेरे से बहुत अधिक चालाक हैं; बाधाओं वे इसे बेहतर और तेजी से किया है। जब तक आप वास्तव में इसे तेज नहीं बना सकते (यानी: हमेशा माप!)
  • धोखा : कुछ मामलों में यद्यपि आपकी समस्या के लिए एक सटीक गणना मौजूद हो सकती है, आपको 'सटीक' की आवश्यकता नहीं हो सकती है, कभी-कभी एक सन्निकटन 'काफी अच्छा' हो सकता है और सौदे में बहुत तेज हो सकता है। अपने आप से पूछें, क्या यह वास्तव में मायने रखता है अगर जवाब 1% से बाहर है? 5%? 10% भी?
    नीचे-किनारे : ठीक है ... उत्तर सटीक नहीं होगा।

32
Precomputation हमेशा मदद नहीं करता है, और यह कभी-कभी चोट भी पहुंचा सकता है - यदि आपकी लुकअप तालिका बहुत बड़ी है, तो यह आपके कैश प्रदर्शन को मार सकती है।
एडम रोसेनफील्ड

37
धोखा अक्सर जीत हो सकती है। मेरे पास एक रंग सुधार प्रक्रिया थी जो कोर में एक 3x3 मैट्रिक्स के साथ 3-वेक्टर डॉटेड थी। सीपीयू में हार्डवेयर का एक गुणक होता था, जो क्रॉस की कुछ शर्तों को छोड़ देता था और इसे करने के अन्य सभी तरीकों की तुलना में वास्तविक तेजी से आगे बढ़ता था, लेकिन केवल 4x4 मैट्रिस और फ्लोट्स के 4-वैक्टर का समर्थन करता था। अतिरिक्त खाली स्लॉट के चारों ओर ले जाने के लिए कोड को बदलना और गणना को स्थिर बिंदु से फ्लोटिंग बिंदु में परिवर्तित करना थोड़ा कम-सटीक लेकिन बहुत तेज परिणाम के लिए अनुमति दी गई है ।
RBerteig

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

6
@Rerteig: सिर्फ "सही पर्याप्त" अनुकूलन के लिए एक अवसर है जो ज्यादातर लोग मेरे अनुभव में याद करते हैं।
मार्टिन थॉम्पसन

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

164

जब आप प्रदर्शन में कोई सुधार नहीं कर सकते हैं - देखें कि क्या आप इसके बजाय कथित प्रदर्शन में सुधार कर सकते हैं ।

आप अपने fooCalc एल्गोरिथ्म को तेज़ी से बनाने में सक्षम नहीं हो सकते हैं, लेकिन अक्सर ऐसे तरीके होते हैं जिससे आपका एप्लिकेशन उपयोगकर्ता के लिए अधिक उत्तरदायी लगता है।

कुछ उदाहरण:

  • यह अनुमान लगाने के बाद कि उपयोगकर्ता क्या अनुरोध करने जा रहा है और उस पर पहले काम करना शुरू कर देगा
  • अंत में एक बार में सभी के बजाय वे परिणाम प्रदर्शित करते हैं
  • सटीक प्रगति मीटर

ये आपके प्रोग्राम को तेज़ नहीं बनाएंगे, लेकिन यह आपके उपयोगकर्ताओं को आपकी गति से अधिक खुश कर सकते हैं।


27
अंत में तेजी से बढ़ने वाली प्रगति पट्टी को बिल्कुल सटीक की तुलना में तेज़ माना जा सकता है। "रीथिंकिंग द प्रोग्रेसिंग बार" (2007) हैरिसन, एमेंटो, कुज़नेत्सोव और बेल उपयोगकर्ताओं के एक समूह पर कई प्रकार के बार का परीक्षण करते हैं और साथ ही साथ संचालन को पुनर्व्यवस्थित करने के कुछ तरीकों पर चर्चा कर रहे हैं ताकि प्रगति तेजी से हो।
एमिल विक्रोत्तम

9
नक्सा, अधिकांश प्रगति बार नकली हैं क्योंकि एक प्रवाह में कई व्यापक रूप से भिन्न चरणों की भविष्यवाणी करना कठिन या कभी-कभी असंभव है। जरा उन सभी सलाखों को देखें जो 99% पर अटक जाती हैं :-(
एमिल विक्रोस्टम

138

मैं अपना अधिकांश जीवन बस इसी जगह बिताता हूं। व्यापक स्ट्रोक आपके प्रोफाइलर को चलाने और इसे रिकॉर्ड करने के लिए मिलते हैं:

  • कैश की याद आती है । डेटा कैश अधिकांश कार्यक्रमों में स्टालों का # 1 स्रोत है। बेहतर स्थानीयता के लिए आक्रामक डेटा संरचनाओं को पुनर्गठित करके कैश हिट दर में सुधार; व्यर्थ बाइट्स को खत्म करने के लिए संरचनाएं और संख्यात्मक प्रकार नीचे पैक करें (और इसलिए कैश कैश बर्बाद); स्टालों को कम करने के लिए जहाँ भी संभव हो, प्रीफ़ैच डेटा।
  • लोड-हिट-स्टोर । पॉइंटर एलियासिंग के बारे में कंपाइलर धारणाएं, और ऐसे मामलों में जहां डेटा को मेमोरी के माध्यम से डिस्कनेक्ट किए गए रजिस्टर सेट के बीच ले जाया जाता है, एक निश्चित पैथोलॉजिकल व्यवहार का कारण बन सकता है जो पूरे सीपीयू पाइपलाइन को लोड ऑप पर साफ़ करने का कारण बनता है। उन स्थानों का पता लगाएं, जहां तैरने वाले, वैक्टर और किलों को एक दूसरे के पास ले जाया जा रहा है और उन्हें खत्म किया जा रहा है। __restrictअलियासिंग के बारे में कंपाइलर से वादा करने के लिए उदारतापूर्वक उपयोग करें ।
  • माइक्रोकैप्ड ऑपरेशन । अधिकांश प्रोसेसरों में कुछ ऐसे ऑपरेशन होते हैं जिन्हें पाइपलाइज़ नहीं किया जा सकता है, लेकिन इसके बजाय रोम में संग्रहीत एक छोटे सबरूटीन को चलाएं। पावरपीसी के उदाहरण पूर्णांक, गुणा, और शिफ्ट-बाय-चर-राशि हैं। समस्या यह है कि इस ऑपरेशन को अंजाम देते समय पूरी पाइपलाइन बंद हो जाती है। इन परिचालनों के उपयोग को समाप्त करने का प्रयास करें या कम से कम उन्हें अपने घटक पाइपलाइन किए गए ऑप्स में तोड़ दें ताकि आप अपने कार्यक्रम के बाकी हिस्सों में जो कुछ भी कर रहे हैं, उस पर सुपरस्क्लेयर प्रेषण का लाभ प्राप्त कर सकें।
  • शाखा गलतफहमी । ये भी पाइपलाइन को खाली करते हैं। ऐसे मामलों का पता लगाएं जहां सीपीयू एक शाखा के बाद पाइप को फिर से भरने में बहुत समय बिता रहा है, और यदि यह अक्सर सही ढंग से भविष्यवाणी करने के लिए उपलब्ध हो तो शाखा संकेत का उपयोग करें। या बेहतर अभी तक, जहां भी संभव हो, सशर्त-चाल के साथ शाखाओं को बदलें विशेष रूप से फ़्लोटिंग पॉइंट ऑपरेशन के बाद क्योंकि उनका पाइप आमतौर पर गहरा होता है और fcmp के बाद स्थिति के झंडे को पढ़ना स्टाल का कारण बन सकता है।
  • अनुक्रमिक फ्लोटिंग-पॉइंट ऑप्स । इन SIMD को बनाओ।

और एक और बात जो मुझे करना पसंद है:

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

8
मैं ज्यादातर Intel VTune और PIX का उपयोग करता हूं। कोई विचार नहीं अगर वे C # के लिए अनुकूल कर सकते हैं, लेकिन वास्तव में एक बार जब आप JIT अमूर्त परत प्राप्त कर लेते हैं, तो इनमें से अधिकांश अनुकूलन आपकी पहुंच से परे होते हैं, सिवाय कैश की स्थानीयता को सुधारने और शायद कुछ शाखाओं से बचने के लिए।
क्रैशवर्क

6
फिर भी, JIT के बाद के आउटपुट पर जाँच से यह पता लगाने में मदद मिल सकती है कि क्या कोई निर्माण है जो सिर्फ JIT चरण के माध्यम से अच्छी तरह से अनुकूलन नहीं करता है ... जांच कभी भी चोट नहीं पहुंचा सकती है, भले ही एक मृत अंत हो।
jerryjvl

5
मुझे लगता है कि कई लोग, जिनमें स्वयं भी शामिल हैं, जीसीसी द्वारा निर्मित इस "डब्ल्यूटीएफ असेंबली" में दिलचस्पी लेंगे। तुम्हारी आवाज़ एक बहुत ही दिलचस्प काम
लगती है

1
Examples on the PowerPC ...<- अर्थात, पावरपीसी के कुछ कार्यान्वयन। पावरपीसी एक आईएसए है, सीपीयू नहीं।
बिली ओनली

1
@BillyONeal यहां तक ​​कि आधुनिक x86 हार्डवेयर पर, इमुल पाइपलाइन को रोक सकता है; देखें "Intel® 64 और IA-32 आर्किटेक्चर ऑप्टिमाइज़ेशन रेफरेंस मैनुअल" .213.3.2.3.3: "पूर्णांक निर्देश को निष्पादित करने के लिए कई चक्र लगते हैं। वे ऐसे पाइपलाइन किए जाते हैं कि एक पूर्णांक निर्देश और एक अन्य लंबी-अक्षीय अनुदेश में आगे प्रगति कर सकते हैं। निष्पादन चरण। हालांकि, पूर्णांक निर्देश अन्य एकल-चक्र पूर्णांक निर्देशों को प्रोग्राम ऑर्डर की आवश्यकता के कारण जारी करने से रोकेंगे। " इसलिए आमतौर पर शब्द-संरेखित सरणी आकारों का उपयोग करना बेहतर होता है और lea
क्रैशवर्क्स

78

उस पर अधिक हार्डवेयर फेंको!


30
अधिक हार्डवेयर हमेशा एक विकल्प नहीं होता है जब आपके पास सॉफ़्टवेयर होता है जो कि पहले से ही क्षेत्र में हार्डवेयर पर चलने की उम्मीद करता है।
डग टी।

76
उपभोक्ता सॉफ्टवेयर बनाने वाले किसी व्यक्ति के लिए बहुत उपयोगी उत्तर नहीं: ग्राहक आपको यह कहते हुए नहीं सुनना चाहता है कि "तेज कंप्यूटर खरीदें।" खासकर यदि आप वीडियो गेम कंसोल जैसी किसी चीज को लक्षित करने के लिए सॉफ्टवेयर लिख रहे हैं।
क्रैश

19
@Crashworks, या उस मामले के लिए, एक एम्बेडेड सिस्टम। जब अंतिम विशेषता अंत में है और बोर्डों का पहला बैच पहले से ही घूम रहा है, यह पता लगाने का क्षण नहीं है कि आपको पहले स्थान पर एक तेज सीपीयू का उपयोग करना चाहिए ...
RBerteig

71
मुझे एक बार एक प्रोग्राम को डिबग करना पड़ा था जिसमें एक बड़ी मेमोरी लीक थी - इसका वीएम आकार लगभग 1Mb प्रति घंटे बढ़ गया। एक सहकर्मी ने मजाक में कहा कि मुझे केवल एक स्थिर दर पर मेमोरी जोड़ने की आवश्यकता थी । :)
j_random_hacker

9
अधिक हार्डवेयर: आह हाँ औसत दर्जे की डेवलपर की जीवन रेखा। मैं नहीं जानता कि कितनी बार मैंने सुना है "एक और मशीन जोड़ें और क्षमता दोगुनी करें!"
ओलोफ फोर्शेल

58

अधिक सुझाव:

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

  • मूव I / O अप-फ्रंट : एक गणना अप-फ्रंट के लिए आपके द्वारा आवश्यक सभी डेटा को लोड करें, ताकि आप को दोहराया न जाए I / O एक महत्वपूर्ण एल्गोरिथ्म के मूल के भीतर इंतजार कर रहा है (और शायद परिणामस्वरूप दोहराया गया डिस्क चाहता है, जब एक हिट में सभी डेटा लोड करने से मांग करने से बचा जा सकता है)।

  • विलंब I / O : गणना समाप्त होने तक अपने परिणाम न लिखें, उन्हें डेटा संरचना में संग्रहीत करें और फिर हार्ड वर्क होने पर अंत में एक बार में बाहर निकाल दें।

  • थ्रेडेड I / O : उन लोगों के लिए जो पर्याप्त साहस करते हैं, 'I / O अप-फ्रंट' या 'Delay I / O' को वास्तविक गणना के साथ लोडिंग को एक समानांतर धागे में ले जाकर जोड़ते हैं, ताकि जब आप अधिक डेटा लोड कर रहे हों तो आप काम कर सकें आपके पास पहले से मौजूद डेटा की गणना पर, या जब आप डेटा के अगले बैच की गणना करते हैं तो आप एक साथ अंतिम बैच से परिणाम लिख सकते हैं।


3
ध्यान दें कि "IO को समानांतर सूत्र में ले जाना" को कई प्लेटफार्मों (जैसे Windows NT) पर अतुल्यकालिक IO के रूप में किया जाना चाहिए।
बिली ओनेल

2
I / O वास्तव में एक महत्वपूर्ण बिंदु है, क्योंकि यह धीमा है और इसमें विशाल विलंबताएं हैं, और आप इस सलाह के साथ तेजी से प्राप्त कर सकते हैं, लेकिन यह अभी भी मौलिक रूप से त्रुटिपूर्ण है: अंक विलंबता (जिसे छिपाया जाना है) और syscall हेड ( जिसे I / O कॉल की संख्या को कम करके कम करना होगा)। सबसे अच्छी सलाह यह है: mmap()इनपुट के लिए उपयोग , उचित madvise()कॉल करें और aio_write()आउटपुट के बड़े हिस्से (= कुछ MiB) लिखने के लिए उपयोग करें।
विस्फ़ोटक - मोनिका

1
विशेष रूप से जावा में लागू करने के लिए यह अंतिम विकल्प काफी आसान है। इसने मेरे द्वारा लिखे गए अनुप्रयोगों के लिए बहुत बड़ा प्रदर्शन दिया। एक अन्य महत्वपूर्ण बिंदु (I / O आगे बढ़ने से अधिक) इसे SEQUENTIAL और बड़े-ब्लॉक I / O बनाना है। डिस्क रीड समय के कारण छोटे रीड्स के बहुत सारे 1 से अधिक महंगे हैं।
BobMcGee

एक बिंदु पर मैंने I / O से बचने में धोखा दिया, बस गणना से पहले अस्थायी रूप से सभी फाइलों को रैम डिस्क पर ले जाकर उन्हें बाद में वापस ले जाना। यह गंदा है, लेकिन ऐसी स्थिति में उपयोगी हो सकता है जहाँ आप I / O कॉल करने वाले तर्क को नियंत्रित नहीं करते हैं।
एमडी

48

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

अधिकांश डेटाबेस में कर्सर से बचें। साथ ही लूपिंग से बचें। ज्यादातर समय, डेटा एक्सेस को सेट-आधारित होना चाहिए, रिकॉर्ड प्रोसेसिंग द्वारा रिकॉर्ड नहीं किया जाना चाहिए। जब आप एक बार में 1,000,000 रिकॉर्ड सम्मिलित करना चाहते हैं, तो एक भी रिकॉर्ड संग्रहीत प्रक्रिया का पुन: उपयोग नहीं करना शामिल है।

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

सहसंबद्ध उपवर्गों के उपयोग से बचें। जॉइन का उपयोग करें (जहां संभव हो वहां से व्युत्पन्न टेबल में शामिल हों) (मुझे पता है कि यह माइक्रोसॉफ्ट एसक्यूएल सर्वर के लिए सही है, लेकिन एक अलग बैकएंड का उपयोग करते समय सलाह का परीक्षण करें)।

सूचकांक, सूचकांक, सूचकांक। और उन आँकड़ों को अपडेट करवाएँ जो आपके डेटाबेस पर लागू हैं।

क्वेरी को सारगर्भित बनाएँ । मतलब उन चीजों से बचें जो इंडेक्स का उपयोग करना असंभव बनाते हैं जैसे वाइल्डकार्ड का उपयोग करना जैसे कि एक क्लॉज के पहले चरित्र में या जॉइन में एक फ़ंक्शन या जहां एक स्टेटमेंट के बाएं हिस्से के रूप में।

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

ट्रिगर में कभी भी किसी भी तरह का लूप न डालें!

अधिकांश डेटाबेस में यह जांचने का एक तरीका है कि क्वेरी निष्पादन कैसे किया जाएगा। Microsoft SQL सर्वर में इसे निष्पादन योजना कहा जाता है। यह देखने के लिए कि समस्या वाले क्षेत्र कहां पड़े हैं, पहले उन्हें देखें।

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

डेटाबेस से वास्तव में क्या भेजा जा रहा है, यह पता लगाने के लिए किसी प्रकार के प्रोफाइलर टूल का उपयोग करें। मैं अतीत में एक समय को याद कर सकता हूं जहां हम यह पता नहीं लगा सके कि संग्रहित प्रक्रिया तेज होने पर पृष्ठ लोड करने के लिए इतना धीमा क्यों था और प्रोफाइलिंग के माध्यम से पता चला कि वेबपेज एक बार के बजाय कई बार क्वेरी के लिए पूछ रहा था।

प्रोफाइलर आपको यह पता लगाने में भी मदद करेगा कि कौन अवरुद्ध कर रहा है। कुछ प्रश्न जो अकेले चलने के दौरान जल्दी निष्पादित होते हैं, अन्य प्रश्नों से तालों के कारण वास्तव में धीमा हो सकते हैं।


29

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

ये वे प्रभाव हैं जिन्हें आपको प्रबंधित करने की आवश्यकता है। कभी-कभी माइक्रो आपके कोड को प्रबंधित करने के माध्यम से, लेकिन कभी-कभी सावधानीपूर्वक विचार और रिफैक्टिंग के माध्यम से।

बहुत सारी टिप्पणियों में पहले से ही कैश फ्रेंडली कोड का उल्लेख है। इसके कम से कम दो अलग-अलग स्वाद हैं:

  • मेमरी लाने से बचें।
  • कम स्मृति बस दबाव (बैंडविड्थ)।

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

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

डेटा को तंग करना और सुनिश्चित करना कि आप हॉट लूप में कैश लाइनों में सभी डेटा का उपयोग करते हैं, इन अन्य प्रभावों से बचने में मदद करेगा, और कैश में अधिक उपयोगी डेटा को फिट करने की अनुमति देगा ।


25
  • आप किस हार्डवेयर पर चल रहे हैं? क्या आप प्लेटफ़ॉर्म-विशिष्ट अनुकूलन (जैसे वैश्वीकरण) का उपयोग कर सकते हैं?
  • क्या आप एक बेहतर संकलक प्राप्त कर सकते हैं? जीसीसी से इंटेल पर एग स्विच?
  • क्या आप अपने एल्गोरिथ्म को समानांतर में चला सकते हैं?
  • क्या आप डेटा को पुनर्गठित करके कैश मिस को कम कर सकते हैं?
  • क्या आप दावे को अक्षम कर सकते हैं?
  • अपने कंपाइलर और प्लेटफॉर्म के लिए माइक्रो-ऑप्टिमाइजेशन। की शैली में, "अगर / किसी और पर, सबसे सामान्य कथन पहले रखें"

4
"जीसीसी से
एलएलवीएम पर

4
क्या आप अपने एल्गोरिथ्म को समानांतर में चला सकते हैं? - उलटा भी लागू होता है
justin

4
यह सच है कि, धागे की मात्रा को कम करना एक अच्छा अनुकूलन हो सकता है
जोहान कोटलिंस्की

पुन: माइक्रो-ऑप्टिमाइज़िंग: यदि आप संकलक के एएसएम आउटपुट की जांच करते हैं, तो आप अक्सर स्रोत को बेहतर एएसएम बनाने में हाथ से पकड़ सकते हैं। देखें कि यह C ++ कोड Collatz अनुमान के परीक्षण के लिए मेरे हाथ से लिखे गए विधानसभा से अधिक तेज़ क्यों है? आधुनिक x86 पर संकलक की मदद या पिटाई के बारे में अधिक जानकारी के लिए।
पीटर कॉर्डेस

17

हालांकि मुझे माइक डनलैवी का जवाब पसंद है, वास्तव में यह एक बहुत अच्छा जवाब है, उदाहरण के लिए, मुझे लगता है कि यह केवल इस प्रकार व्यक्त किया जा सकता है:

पता करें कि पहले सबसे बड़ी मात्रा में क्या होता है, और क्यों समझें।

यह उस समय की पहचान प्रक्रिया है, जो आपको समझने में मदद करती है कि आपको अपने एल्गोरिथ्म को कहाँ परिष्कृत करना चाहिए। यह एकमात्र सर्वव्यापी भाषा अज्ञेय उत्तर है जो मुझे एक समस्या से मिल सकता है जो पहले से ही पूरी तरह से अनुकूलित होना चाहिए। इसके अलावा आप गति के लिए अपनी खोज में स्वतंत्र होना चाहते हैं वास्तुकला।

इसलिए जब एल्गोरिथ्म को अनुकूलित किया जा सकता है, तो इसका कार्यान्वयन नहीं हो सकता है। पहचान आपको यह जानने की अनुमति देती है कि कौन सा हिस्सा है: एल्गोरिथ्म या कार्यान्वयन। इसलिए जो भी समय आपकी समीक्षा के लिए सबसे महत्वपूर्ण उम्मीदवार है। लेकिन जब से आप कहते हैं कि आप पिछले कुछ% को निचोड़ना चाहते हैं, तो आप कम हिस्सों की भी जांच कर सकते हैं, जिन भागों की आपने पहले बारीकी से जांच नहीं की है।

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

एचपीएच, एसोद्मोव।


16

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

दूसरी ओर, Google लोगों को परियोजनाओं, उपकरणों और बुनियादी ढांचे में कुछ मुद्दों को हल करने के लिए बहुत सारी जनशक्ति और संसाधन फेंकने के लिए जाना जाता है, जैसे कि इंजीनियरों की एक समर्पित टीम होने से उदाहरण के लिए पूरे कार्यक्रम का अनुकूलन। Google-विशिष्ट उपयोग के मामले परिदृश्यों के लिए इसे तैयार करने के लिए जीसीसी इंटर्नल को हैक करना।

इसी तरह, किसी एप्लिकेशन को प्रोफाइल करने का मतलब अब प्रोग्राम कोड को प्रोफाइल करना नहीं है, बल्कि सिस्टम के दृष्टिकोण से अतिरेक और अनुकूलन क्षमता की पहचान करने के लिए इसके सभी आस-पास के सिस्टम और इन्फ्रास्ट्रक्चर (नेटवर्क, स्विच, सर्वर, RAID सरणियां) भी हैं।


15
  • इनलाइन दिनचर्या (कॉल / वापसी और पैरामीटर को समाप्त करना)
  • टेबल लुक अप (यदि वे तेज़ हैं) के साथ परीक्षण / स्विच को समाप्त करने का प्रयास करें
  • अनूप लूप्स (डफ का उपकरण) उस बिंदु पर जहां वे बस सीपीयू कैश में फिट होते हैं
  • मेमोरी एक्सेस का स्थानीयकरण करें ताकि आपके कैश को उड़ा न सकें
  • यदि ऑप्टिमाइज़र पहले से ऐसा नहीं कर रहा है, तो संबंधित गणनाओं का स्थानीयकरण करें
  • यदि अनुकूलक पहले से ही ऐसा नहीं कर रहा है, तो लूप आक्रमणकारियों को हटा दें

2
IIRC डफ का उपकरण बहुत ही कम तेज है। केवल जब ऑप बहुत छोटा होता है (एक एकल छोटी गणित अभिव्यक्ति की तरह)
बीसीएस

12
  • जब आप इस बिंदु पर पहुँचते हैं कि आप कुशल एल्गोरिदम का उपयोग कर रहे हैं, तो यह एक सवाल है कि आपको और अधिक गति या स्मृति की आवश्यकता क्या है । अधिक गति के लिए स्मृति में "भुगतान" करने के लिए कैशिंग का उपयोग करें या स्मृति पदचिह्न को कम करने के लिए गणना का उपयोग करें।
  • यदि संभव हो (और अधिक लागत प्रभावी) समस्या पर हार्डवेयर फेंकते हैं - तेजी से सीपीयू, अधिक मेमोरी या एचडी समस्या को तेजी से हल कर सकता है फिर इसे कोड करने की कोशिश कर रहा है।
  • यदि संभव हो तो समानांतरकरण का उपयोग करें - कई थ्रेड्स पर कोड का भाग चलाएँ।
  • इस काम के लिए सही उपकरण का उपयोग करें । कुछ प्रोग्रामिंग भाषाएँ अधिक कुशल कोड बनाती हैं, प्रबंधित कोड (यानी जावा / .NET) के उपयोग से विकास को गति मिलती है, लेकिन देशी प्रोग्रामिंग भाषाएं तेजी से चलने वाला कोड बनाती हैं।
  • माइक्रो ऑप्टिमाइज़ेशन । केवल लागू थे आप कोड के छोटे टुकड़ों को गति देने के लिए अनुकूलित असेंबली का उपयोग कर सकते हैं, सही स्थानों पर एसएसई / वेक्टर अनुकूलन का उपयोग करके प्रदर्शन को बढ़ा सकते हैं।

12

विभाजन और जीत

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


9
फ्लाईवेटर "स्मैक" ध्वनि के लिए +1 जो मैंने आखिरी वाक्य पढ़ते समय सुना था।
ब्रायन बोएचर

11

सबसे पहले, जैसा कि कई पूर्व उत्तरों में बताया गया है, जानें कि आपके प्रदर्शन को क्या काटता है - यह मेमोरी या प्रोसेसर या नेटवर्क या डेटाबेस या कुछ और है। उसके आधार पर ...

  • ... अगर यह स्मृति है - नूथ द्वारा लंबे समय पहले लिखी गई पुस्तकों में से एक, "द आर्ट ऑफ़ कंप्यूटर प्रोग्रामिंग" श्रृंखला में से एक खोजें। सबसे अधिक संभावना है कि यह छंटाई और खोज के बारे में एक है - अगर मेरी मेमोरी गलत है, तो आपको यह पता लगाना होगा कि वह धीमे टेप डेटा भंडारण से कैसे निपटना है। मानसिक रूप से अपने निचोड़ को अंतिम कुछ प्रतिशत तक बदल दें ? यदि यह वास्तव में कुछ है तो आप सबसे अधिक संभावना जीतेंगे। याददाश्त / टेप को जोड़ी को क्रमशः कैश / मेन मेमोरी (या L1 / L2 कैश की जोड़ी में) में बदलें। उनके द्वारा बताई गई सभी तरकीबों का अध्ययन करें - यदि आपको ऐसी कोई चीज़ नहीं मिलती है जो आपकी समस्या को हल करती है, तो पेशेवर शोध करने के लिए पेशेवर कंप्यूटर वैज्ञानिक को नियुक्त करें। यदि आपकी मेमोरी इश्यू एफएफटी के साथ संयोग से है (रेडिक्स -2 तितलियों को करते समय बिट-रिवर्स इंडेक्स पर कैश की कमी होती है) तो एक वैज्ञानिक को काम पर न रखें - इसके बजाय, मैन्युअल रूप से पास-पास-पास एक का अनुकूलन करें जब तक कि आप '

  • ... अगर यह प्रोसेसर है - विधानसभा भाषा पर स्विच करें। प्रोसेसर प्रोसेसर का अध्ययन - क्या टिक , वीएलआईडब्ल्यू, सिमडी लेता है। समारोह कॉल सबसे अधिक संभावना है टिक-खाने वाले। लूप ट्रांसफॉर्मेशन सीखें - पाइपलाइन, अनरोल। गुणकों और विभाजनों को बिट शिफ्ट्स के साथ बदली / प्रक्षेपित किया जा सकता है (छोटे पूर्णांकों द्वारा गुणाओं को परिवर्धन के साथ बदली जा सकती है)। छोटे डेटा के साथ ट्रिक्स आज़माएं - यदि आप भाग्यशाली हैं कि 64 बिट्स वाला एक निर्देश 32 पर दो या 4 पर 16 या 8 बिट्स ऑन 8 बिट्स के साथ बदली हो सकता है। कोशिश भी करेंअब औरडेटा - उदाहरण के लिए आपकी फ्लोट गणना विशेष प्रोसेसर पर डबल वाले की तुलना में धीमी हो सकती है। यदि आपके पास त्रिकोणमितीय सामान है, तो इसे पूर्व-गणना की गई तालिकाओं के साथ लड़ें; यह भी ध्यान रखें कि छोटे मूल्य की साइन को उस मान से बदला जा सकता है यदि परिशुद्धता का नुकसान अनुमत सीमा के भीतर हो।

  • ... अगर यह नेटवर्क है - डेटा को संपीड़ित करने के बारे में सोचें जो आप इसे पार करते हैं। XML ट्रांसफ़र को बाइनरी से बदलें। अध्ययन प्रोटोकॉल। टीसीपी के बजाय यूडीपी का प्रयास करें यदि आप किसी तरह डेटा हानि को संभाल सकते हैं।

  • ... अगर यह डेटाबेस है, ठीक है, किसी भी डेटाबेस फोरम पर जाएं और सलाह मांगें। इन-मेमोरी डेटा-ग्रिड, क्वेरी प्लान आदि का अनुकूलन आदि।

HTH :)


9

कैशिंग! एक सस्ता तरीका (प्रोग्रामर प्रयास में) लगभग कुछ भी तेजी से बनाने के लिए अपने प्रोग्राम के किसी भी डेटा आंदोलन क्षेत्र में एक कैशिंग एब्स्ट्रक्शन परत को जोड़ना है। यह I / O हो या केवल वस्तुओं या संरचनाओं का निर्माण / निर्माण। अक्सर कारखाने की कक्षाओं और पाठक / लेखकों के लिए कैश जोड़ना आसान होता है।

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


8

मुझे लगता है कि यह पहले से ही एक अलग तरीके से कहा गया है। लेकिन जब आप एक प्रोसेसर गहन एल्गोरिथ्म के साथ काम कर रहे होते हैं, तो आपको हर चीज की कीमत पर सबसे आंतरिक लूप के अंदर सब कुछ सरल करना चाहिए।

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

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


8

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

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

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

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

  • समानांतर : अनुक्रमिक लेनदेन की तलाश करें जो तार्किक रूप से सख्ती से क्रमिक रूप से जारी करने की आवश्यकता नहीं है, और समानांतर में उन्हें जारी करने के लिए सिस्टम को फिर से काम करते हैं। मैंने एक मामले से निपटा, जहां एंड-टू-एंड अनुरोध में अंतर्निहित नेटवर्क विलंब ~ 2s था, जो कि एकल लेनदेन के लिए कोई समस्या नहीं थी, लेकिन जब उपयोगकर्ता के ग्राहक नियंत्रण प्राप्त करने से पहले 6 अनुक्रमिक 2s दौर यात्राएं आवश्यक थीं। , यह हताशा का एक बड़ा स्रोत बन गया। यह जानते हुए कि ये लेनदेन वास्तव में स्वतंत्र थे, उन्हें समानांतर में निष्पादित करने की अनुमति दी गई, जिससे अंतिम-उपयोगकर्ता विलंब को एक दौर की यात्रा की लागत के करीब पहुंच गया।

  • गठबंधन : जहां अनुक्रमिक अनुरोधों को क्रमिक रूप से निष्पादित किया जाना चाहिए, उन्हें एक और अधिक व्यापक अनुरोध में संयोजित करने के अवसरों की तलाश करें। विशिष्ट उदाहरणों में नई संस्थाओं का निर्माण शामिल है, इसके बाद उन संस्थाओं को अन्य मौजूदा संस्थाओं से संबंधित करने के अनुरोध शामिल हैं।

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

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

उपरोक्त चरणों में, मैं एप्लिकेशन संबंधित ऑप्टिमाइज़ेशन प्रक्रिया पर ध्यान केंद्रित करता हूं, लेकिन निश्चित रूप से आपको यह सुनिश्चित करना होगा कि अंतर्निहित नेटवर्क स्वयं आपके एप्लिकेशन का समर्थन करने के लिए सबसे कुशल तरीके से कॉन्फ़िगर किया गया है। व्यवसाय में नेटवर्किंग विशेषज्ञों को संलग्न करें और निर्धारित करें कि क्या वे समस्या को संबोधित करने के लिए क्षमता में सुधार, क्यूओएस, नेटवर्क संपीड़न, या अन्य तकनीकों को लागू करने में सक्षम हैं। आमतौर पर, वे आपके आवेदन की जरूरतों को नहीं समझेंगे, इसलिए यह महत्वपूर्ण है कि आप (विश्लेषण चरण के बाद) उनके साथ इस पर चर्चा करें, और किसी भी कीमत के लिए व्यवसाय के मामले को बनाने के लिए भी कहें जो आप उन्हें करने के लिए कह रहे हैं। । मुझे ऐसे मामलों का सामना करना पड़ा है, जहां गलत नेटवर्क कॉन्फ़िगरेशन के कारण एप्लिकेशन डेटा को एक ओवरलैंड लिंक के बजाय एक धीमी सैटेलाइट लिंक पर प्रेषित किया जाता है, केवल इसलिए कि यह टीसीपी पोर्ट का उपयोग कर रहा था जो नेटवर्किंग विशेषज्ञों द्वारा "अच्छी तरह से ज्ञात नहीं था"; स्पष्ट रूप से इस तरह की समस्या को सुधारने पर प्रदर्शन पर एक नाटकीय प्रभाव पड़ सकता है, जिसमें कोई सॉफ्टवेयर कोड या कॉन्फ़िगरेशन परिवर्तन आवश्यक नहीं है।


7

इस सवाल का एक सामान्य जवाब देना बहुत मुश्किल है। यह वास्तव में आपकी समस्या डोमेन और तकनीकी कार्यान्वयन पर निर्भर करता है। एक सामान्य तकनीक जो काफी भाषा तटस्थ है: कोड हॉटस्पॉट की पहचान करें जिन्हें समाप्त नहीं किया जा सकता है, और कोड कोड को हाथ से अनुकूलित करें।


7

अंतिम कुछ% एक बहुत सीपीयू और अनुप्रयोग पर निर्भर बात है ...।

  • कैश आर्किटेक्चर अलग-अलग होते हैं, कुछ चिप्स में ऑन-चिप रैम होती है जिसे आप सीधे मैप कर सकते हैं, ARM (कभी-कभी) में एक वेक्टर यूनिट, SH4 का एक उपयोगी मैट्रिक्स ओपकोड होता है। वहां एक GPU है - शायद एक shader जाने का रास्ता है। TMS320 की छोरों के भीतर शाखाओं के प्रति बहुत संवेदनशील हैं (इसलिए यदि संभव हो तो अलग-अलग छोरों और बाहर की स्थितियों को स्थानांतरित करें)।

सूची जारी होती है .... लेकिन इस प्रकार की चीजें वास्तव में अंतिम उपाय हैं ...

X86 के लिए बनाएँ, और उचित प्रदर्शन प्रोफाइलिंग के लिए कोड के खिलाफ Valgrind / Cachegrind चलाएं। या टेक्सास इंस्ट्रूमेंट्स ' CCStudio में एक मीठा प्रोफाइलर है। तब आपको वास्तव में पता चल जाएगा कि कहां ध्यान केंद्रित करना है ...


7

Did you know that a CAT6 cable is capable of 10x better shielding off extrenal inteferences than a default Cat5e UTP cable?

किसी भी गैर-ऑफ़लाइन परियोजनाओं के लिए, सर्वश्रेष्ठ सॉफ्टवेयर और सर्वश्रेष्ठ हार्डवेयर होने के बावजूद, यदि आपका विवाद कमजोर है, तो वह पतली रेखा डेटा को निचोड़ने और आपको देरी देने वाली है, मिलीसेकंड में यद्यपि ... लेकिन अगर आप अंतिम बूंदों के बारे में बात कर रहे हैं , जो कुछ बूंदों के लिए भेजा गया, 24/7 किसी भी पैक के लिए भेजा गया या प्राप्त किया गया।


7

पिछले उत्तरों के अनुसार गहराई या जटिल के रूप में लगभग नहीं, लेकिन यहाँ जाता है: (ये अधिक शुरुआती / मध्यवर्ती स्तर हैं)

  • स्पष्ट: सूखा
  • लूप को पीछे की ओर चलाएं ताकि आप हमेशा एक वेरिएबल की बजाय 0 से तुलना करें
  • जब भी आप कर सकते हैं बिटवाइज़ ऑपरेटरों का उपयोग करें
  • मॉड्यूल / कार्यों में दोहरावदार कोड को तोड़ना
  • कैश ऑब्जेक्ट्स
  • स्थानीय चरों में मामूली प्रदर्शन लाभ होता है
  • जितना संभव हो उतना स्ट्रिंग हेरफेर को सीमित करें

4
पीछे की ओर लूपिंग के बारे में: हां, लूप एंड के लिए तुलना तेज होगी। आमतौर पर आप चर का उपयोग स्मृति में अनुक्रमित करने के लिए करते हैं, और इसे उल्टा एक्सेस करने के लिए लगातार कैश मिस (कोई प्रीफ़ैच) के कारण काउंटर उत्पादक हो सकता है।
एंड्रियास रीफ जूल

1
AFAIK, ज्यादातर मामलों में, कोई भी उचित ऑप्टिमाइज़र लूप्स के साथ ठीक करेगा, प्रोग्रामर के बिना स्पष्ट रूप से रिवर्स में चलने के लिए। या तो आशावादी स्वयं लूप को उलट देगा, या इसके पास एक और तरीका है जो समान रूप से अच्छा है। मैंने समान रूप से ASM आउटपुट के लिए समान रूप से नोट किया है (मोटे तौर पर सरल) लूप दोनों आरोही बनाम अधिकतम और अवरोही बनाम 0. लिखा , निश्चित रूप से, मेरे Z80 दिनों में मुझे स्पष्ट रूप से पीछे की ओर लूप लिखने की आदत है, लेकिन मुझे संदेह है कि यह आमतौर पर newbies के लिए उल्लेख है लाल हेरिंग / समय से पहले अनुकूलन, जब पठनीय कोड और अधिक महत्वपूर्ण प्रथाओं को सीखना प्राथमिकताएं होनी चाहिए।
अंडरस्कोर_ड

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

5

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

बेहतर कैश लोकलिटी, लूप अनरोलिंग, बेहतर इंस्ट्रक्शन-लेवल समानता पाने के लिए लंबी निर्भरता चेन को खत्म करने की कोशिश करें। संभव होने पर शाखाओं से अधिक सशर्त चालों को प्राथमिकता दें। जब संभव हो तो SIMD के निर्देशों का पालन करें।

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

खैर, वह, और "एसओ पर कोड दिखाएं और कोड के उस विशिष्ट टुकड़े के लिए अनुकूलन सलाह के लिए पूछें"।


5

अगर बेहतर हार्डवेयर एक विकल्प है तो उसके लिए जरूर जाएं। अन्यथा

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

मैं आपके पहले बराबर में जोड़ दूंगा: अपने कंपाइलर विकल्पों में सभी डिबगिंग जानकारी को बंद करना न भूलें
varnie

5

Google तरीका एक विकल्प है "इसे कैश करें .. जब भी संभव हो डिस्क को न छुएं"


5

यहां कुछ त्वरित और गंदी अनुकूलन तकनीकें हैं जिनका मैं उपयोग करता हूं। मैं इसे 'पहला पास' अनुकूलन मानता हूं।

जानें कि कहां समय व्यतीत होता है पता करें कि समय क्या है। क्या यह फ़ाइल IO है? क्या यह CPU समय है? क्या यह नेटवर्क है? क्या यह डेटाबेस है? यदि यह अड़चन नहीं है तो IO के लिए अनुकूलित करना बेकार है।

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

अनुक्रमित अक्सर डेटाबेस के क्षेत्रों पर अनुक्रमित बनाएँ। आप गति के लिए लगभग हमेशा व्यापार स्थान रख सकते हैं।

लुकअप से बचें लूप के अंदर अनुकूलित होने के लिए, मैं किसी भी लुकअप को करने से बचता हूं। लूप के बाहर ऑफसेट और / या सूचकांक का पता लगाएं और डेटा का पुन: उपयोग करें।

IO को न्यूनतम तरीके से डिजाइन करने का प्रयास करें, जो आपको नेटवर्क कनेक्शन पर विशेष रूप से पढ़ने या लिखने की संख्या को कम करता है

अमूर्त कम करें कोड को अमूर्त करने की अधिक परतों के माध्यम से काम करना पड़ता है, यह धीमा है। महत्वपूर्ण लूप के अंदर, अमूर्त को कम करें (उदाहरण के लिए निचले स्तर के तरीकों को प्रकट करें जो अतिरिक्त कोड से बचें)

एक यूजर इंटरफेस के साथ परियोजनाओं के लिए स्पॉन थ्रेड्स , धीमी कार्यों को प्रीफॉर्म करने के लिए एक नया धागा पैदा करना, एप्लिकेशन को अधिक उत्तरदायी महसूस करता है , हालांकि ऐसा नहीं है।

पूर्व-प्रक्रिया आप आम तौर पर गति के लिए स्थान का व्यापार कर सकते हैं। यदि गणना या अन्य गहन संचालन हैं, तो देखें कि क्या आप महत्वपूर्ण लूप में आने से पहले कुछ जानकारी को रोक सकते हैं।


5

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


5

इस उत्तर को जोड़ने के बाद से मैंने इसे अन्य सभी में शामिल नहीं देखा।

प्रकार और संकेत के बीच निहित रूपांतरण को कम करें:

यह कम से कम C / C ++ पर लागू होता है, भले ही आप पहले से ही सोचते हों हों आप रूपांतरणों से मुक्त हैं - कभी-कभी कार्यों के आसपास संकलक चेतावनी को जोड़ने के लिए इसका परीक्षण अच्छा होता है जिसमें प्रदर्शन की आवश्यकता होती है, विशेषकर लूप के भीतर रूपांतरण के लिए वॉच-आउट।

GCC spesific: आप अपने कोड के आसपास कुछ वर्बोज़ प्रैग्मस जोड़कर इसका परीक्षण कर सकते हैं,

#ifdef __GNUC__
#  pragma GCC diagnostic push
#  pragma GCC diagnostic error "-Wsign-conversion"
#  pragma GCC diagnostic error "-Wdouble-promotion"
#  pragma GCC diagnostic error "-Wsign-compare"
#  pragma GCC diagnostic error "-Wconversion"
#endif

/* your code */

#ifdef __GNUC__
#  pragma GCC diagnostic pop
#endif

मैंने ऐसे मामले देखे हैं जहां आप इस तरह की चेतावनी द्वारा उठाए गए रूपांतरणों को कम करके कुछ प्रतिशत स्पीडअप प्राप्त कर सकते हैं।

कुछ मामलों में मेरे पास सख्त चेतावनी के साथ एक हेडर है जिसे मैं आकस्मिक रूपांतरणों को रोकने के लिए शामिल करता हूं, हालांकि यह एक व्यापार बंद है क्योंकि आप जानबूझकर रूपांतरणों को शांत करने के लिए बहुत सी जातियों को जोड़ सकते हैं जो कोड को कम से कम अधिक अव्यवस्थित कर सकते हैं। लाभ।


यही कारण है कि मुझे ऐसा लगता है कि OCaml में, संख्यात्मक प्रकारों के बीच कास्टिंग करना जरूरी है।
गयूस

@ Gaius निष्पक्ष बिंदु - लेकिन कई मामलों में भाषाओं को बदलना एक यथार्थवादी विकल्प नहीं है। चूँकि C / C ++ का उपयोग व्यापक रूप से किया जाता है, इसलिए यह उनके संकलक को विशिष्ट बनाने में सक्षम होने के लिए भी उपयोगी होता है।
ideasman42

4

कभी-कभी आपके डेटा के लेआउट को बदलने से मदद मिल सकती है। C में, आप सरणी या संरचनाओं से सरणियों की संरचना, या इसके विपरीत स्विच कर सकते हैं।


4

ओएस और फ्रेमवर्क टीक।

यह एक ओवरकिल लग सकता है, लेकिन इसके बारे में इस तरह से सोचें: ऑपरेटिंग सिस्टम और फ्रेमवर्क कई चीजों को करने के लिए डिज़ाइन किए गए हैं। आपका आवेदन केवल बहुत विशिष्ट चीजें करता है। यदि आप प्राप्त कर सकते हैं कि OS को वही करना चाहिए जो आपके एप्लिकेशन को चाहिए और आपके एप्लिकेशन को यह समझ में आए कि फ्रेमवर्क (php, .net, java) कैसे काम करता है, तो आप अपने हार्डवेयर से बहुत बेहतर प्राप्त कर सकते हैं।

उदाहरण के लिए, फेसबुक ने लिनक्स में कुछ कर्नेल स्तर की चीज़ों को बदल दिया, कैसे मेमेकैड काम करता है (उदाहरण के लिए उन्होंने एक मेम्केड प्रॉक्सी लिखा था, और टीसीपी के बजाय यूडीपी का इस्तेमाल किया )।

इसके लिए एक और उदाहरण Window2008 है। Win2K8 का एक ऐसा संस्करण है जिसे आप एक्स एप्लियेंस (जैसे वेब-एप्स, सर्वर एप्स) को चलाने के लिए सिर्फ मूल ओएस को स्थापित कर सकते हैं। यह ओवरहेड को बहुत कम कर देता है जो ओएस के चलने की प्रक्रियाओं पर होता है और आपको बेहतर प्रदर्शन देता है।

बेशक, आपको हमेशा पहले चरण के रूप में अधिक हार्डवेयर में फेंकना चाहिए ...


2
अन्य सभी दृष्टिकोणों के विफल होने के बाद एक वैध दृष्टिकोण होगा, या यदि विशिष्ट रूप से कम प्रदर्शन के लिए एक विशिष्ट ओएस या फ्रेमवर्क सुविधा जिम्मेदार थी, लेकिन उस परियोजना को खींचने के लिए आवश्यक विशेषज्ञता और नियंत्रण का स्तर हर परियोजना के लिए उपलब्ध नहीं हो सकता है।
एंड्रयू नीली
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.