अनुकूलन को स्थानीय रखें, उन्हें स्पष्ट करें, उन्हें अच्छी तरह से प्रलेखित करें और स्रोत कोड और रन-टाइम प्रदर्शन के मामले में दोनों को एक दूसरे के साथ अनुकूलित संस्करणों की तुलना करना आसान बना दें।
पूरा जवाब
यदि इस तरह के अनुकूलन आपके उत्पाद के लिए वास्तव में महत्वपूर्ण हैं , तो आपको न केवल यह जानने की आवश्यकता है कि अनुकूलन पहले क्यों उपयोगी थे, बल्कि डेवलपर्स को यह जानने में मदद करने के लिए पर्याप्त जानकारी प्रदान करते हैं कि क्या वे भविष्य में उपयोगी होंगे।
आदर्श रूप से, आपको अपनी निर्माण प्रक्रिया में प्रदर्शन परीक्षण को सुनिश्चित करने की आवश्यकता होती है, इसलिए आपको पता चलता है कि नई प्रौद्योगिकियां पुराने अनुकूलन को अमान्य कर देती हैं।
याद है:
कार्यक्रम अनुकूलन का पहला नियम: यह मत करो।
कार्यक्रम अनुकूलन का दूसरा नियम (केवल विशेषज्ञों के लिए!): अभी तक ऐसा न करें। "
- माइकल ए। जैक्सन
यह जानने के लिए कि क्या अब समय के लिए बेंचमार्किंग और परीक्षण की आवश्यकता है।
जैसा कि आप उल्लेख करते हैं, अत्यधिक अनुकूलित कोड के साथ सबसे बड़ी समस्या यह है कि इसे बनाए रखना मुश्किल है, जहां तक संभव हो, आपको अनुकूलित भागों को अडॉप्ट किए गए भागों से अलग रखने की आवश्यकता है। चाहे आप कंपाइल टाइम लिंकिंग के माध्यम से करते हैं, रनटाइम वर्चुअल फंक्शन कॉल करते हैं या बीच में कुछ नहीं होना चाहिए। क्या बात है कि जब आप अपने परीक्षण चलाते हैं, तो आप उन सभी संस्करणों के खिलाफ परीक्षण करने में सक्षम होना चाहते हैं, जिनमें आप वर्तमान में रुचि रखते हैं।
मैं इस तरह से एक सिस्टम बनाने के लिए इच्छुक हूं कि उत्पादन कोड के मूल अडॉप्ट किए गए संस्करण को हमेशा कोड के इरादे को समझने के लिए इस्तेमाल किया जा सकता है , फिर इसके साथ अलग-अलग अनुकूलित मॉड्यूल का निर्माण करें, जिसमें अनुकूलित संस्करण या संस्करण शामिल हों, स्पष्ट रूप से जहां भी दस्तावेज हों अनुकूलित संस्करण बेस-लाइन से भिन्न होता है। जब आप अपने परीक्षण (इकाई और एकीकरण) चलाते हैं, तो आप इसे बिना किसी अतिरिक्त संस्करण और सभी मौजूदा अनुकूलित मॉड्यूल पर चलाते हैं ।
उदाहरण
उदाहरण के लिए, आपको एक फास्ट फूरियर ट्रांसफ़र फ़ंक्शन की सुविधा देता है। हो सकता है कि आपके पास एक बुनियादी, एल्गोरिथम कार्यान्वयन fft.c
और में परीक्षण हो fft_tests.c
।
फिर साथ में पेंटियम आता है और आप MMX निर्देशोंfft_mmx.c
का उपयोग करके निश्चित बिंदु संस्करण को लागू करने का निर्णय लेते हैं । बाद में पेंटियम 3 आता है और आप एक संस्करण जोड़ने का निर्णय लेते हैं जिसमें स्ट्रीमिंग सिमडी एक्सटेंशन का उपयोग किया जाता है ।fft_sse.c
अब आप CUDA जोड़ना चाहते हैं , इसलिए आप जोड़ते हैं fft_cuda.c
, लेकिन पाते हैं कि आप जिस टेस्ट डेटासेट का उपयोग वर्षों से कर रहे हैं, वह CUDA संस्करण SSE संस्करण की तुलना में धीमा है! आप कुछ विश्लेषण करते हैं और एक डेटासेट को जोड़ते हैं जो 100 गुना बड़ा है और आपको वह गति मिलती है जिसकी आप अपेक्षा करते हैं, लेकिन अब आप जानते हैं कि CUDA संस्करण का उपयोग करने के लिए सेट-अप समय महत्वपूर्ण है और छोटे डेटासेट के साथ आपको एक का उपयोग करना चाहिए उस सेट-अप लागत के बिना एल्गोरिथ्म।
इन मामलों में से प्रत्येक में आप एक ही एल्गोरिदम को लागू कर रहे हैं, सभी को एक ही तरह से व्यवहार करना चाहिए, लेकिन अलग-अलग आर्किटेक्चर पर अलग-अलग क्षमता और गति के साथ चलेगा (यदि वे बिल्कुल भी चलेंगे)। हालांकि, कोड के दृष्टिकोण से, आप स्रोत फ़ाइलों की किसी भी जोड़ी की तुलना यह पता लगाने के लिए कर सकते हैं कि एक ही इंटरफ़ेस को अलग-अलग तरीकों से क्यों लागू किया जाता है और आमतौर पर, सबसे आसान तरीका मूल अनोप्टीमाइज़्ड संस्करण को वापस संदर्भित करना होगा।
सभी एक OOP कार्यान्वयन के लिए जाते हैं, जहां एक आधार वर्ग जो अनप्टीमाइज्ड एल्गोरिथ्म को लागू करता है, और व्युत्पन्न वर्ग अलग-अलग अनुकूलन लागू करते हैं।
महत्वपूर्ण बात यह है कि जो चीजें समान हैं , उन्हें वही रखें , ताकि अंतर स्पष्ट हो ।