क्या मैं समय से पहले अनुकूलन कर रहा हूं?


9

मैं वर्तमान में C ++ में एक घटक-आधारित वास्तुकला के डिजाइन चरण में हूं।

मेरे वर्तमान डिज़ाइन में सुविधाओं का उपयोग शामिल है जैसे:

  • std::vectorके एस std::shared_ptrएस घटकों धारण करने के लिए
  • std::dynamic_pointer_cast
  • std::unordered_map<std::string,[yada]>

घटक गेम-जैसे सॉफ़्टवेयर में आवश्यक विभिन्न वस्तुओं के डेटा और तर्क का प्रतिनिधित्व करेंगे, जैसे ग्राफिक्स, भौतिकी, एआई, ऑडियो आदि।

मैंने सभी जगह पढ़ा है कि कैश मिस प्रदर्शन पर कठिन है, इसलिए मैंने कुछ परीक्षण किए, जिससे मुझे विश्वास हो गया कि, वास्तव में, यह एक एप्लिकेशन को धीमा कर सकता है।

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

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

या मैं सिर्फ समय से पहले अनुकूलन करने में फंस गया हूं?


3
मैं एक डिजाइन पर समझौता करने के लिए बहुत अनिच्छुक होगा जिसने प्रदर्शन के मुद्दों की परवाह किए बिना बाद में बदलना बहुत मुश्किल बना दिया। अगर आप कर सकते हैं तो इससे बचें। ऐसे कई डिज़ाइन हैं जो लचीले और तेज़ दोनों हैं।
कैंडिड_ऑरेंज

1
विवरणों को जानने के बिना भी, इस सवाल का जवाब लगभग हमेशा एक शानदार "हाँ !!" है।
मावग का कहना है कि मोनिका जूल

2
@Mawg "... फिर भी हमें उस गंभीर 3% में अपने अवसरों को पारित नहीं करना चाहिए।" चूंकि यह डिजाइन का मूल है, मुझे कैसे पता चल सकता है कि मैं इस 3% पर काम कर रहा हूं?
वाइलाकोर्ट

1
एक अतिशयोक्तिपूर्ण बिंदु, अलेक्जेंड्रे (+1), और, हाँ, मुझे पता है कि पिछली आधी बोली, जो लगभग कभी उल्लेख नहीं किया जाता है :-) लेकिन, उससे पहले मेरी टिप्पणी पर वापस जाने के लिए (जो कि पूर्वस्कूली उत्तर में परिलक्षित होता है) , the answer to this question is almost always a resounding "YES !!"। मुझे अभी भी लगता है कि इसे पहले काम करना और बाद में ऑप्टिमाइज़ करना बेहतर है, लेकिन वाईएमएमवी, हर किसी की अपनी राय है, जो सभी मान्य हैं, और केवल ओपी वास्तव में अपने स्वयं के व्यक्तिपरक - प्रश्न का उत्तर दे सकता है।
मावग का कहना है कि मोनिका जूल

1
@AlexandreVaillancourt नॉथ का पेपर पढ़ते रहें (पीडीएफ, उद्धरण पृष्ठ के दाईं ओर से आता है जिसे 268, पृष्ठ 8 एक पीडीएफ रीडर में लेबल किया गया है)। "... वह महत्वपूर्ण कोड को ध्यान से देखने के लिए समझदार होगा; लेकिन उसके बाद ही उस कोड की पहचान की गई है। अक्सर एक कार्यक्रम के कुछ हिस्सों के बारे में एक प्राथमिक निर्णय लेने में अक्सर गलती होती है, क्योंकि सार्वभौमिक अनुभव के बाद से यह वास्तव में महत्वपूर्ण है। प्रोग्रामर जो माप उपकरणों का उपयोग कर रहे हैं, उनके सहज अनुमान विफल हो गए हैं। " (उसका जोर)
8bittree

जवाबों:


26

बिना कुछ पढ़े लेकिन शीर्षक: हाँ।

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

सबसे बेवकूफ गलतियों से बचने वाले सॉफ़्टवेयर को लिखें, फिर परीक्षण करें, फिर बाधाओं को ढूंढें, फिर अनुकूलन करें!

Fwiw: https://xkcd.com/1691/


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

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

@ JörgWMittag: सहमत।
स्टीफेन

3

मैं C ++ से परिचित नहीं हूं, लेकिन सामान्य तौर पर यह निर्भर करता है।

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

हालाँकि आपको वांछित प्रमुख प्रदर्शन संकेतक प्राप्त करने के लिए आवेदन का समग्र डिज़ाइन प्राप्त करने की आवश्यकता है।

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


3

अगर आपको पूछना है, तो हाँ। समय से पहले अनुकूलन का अर्थ है अनुकूलन से पहले आपको यकीन है कि एक महत्वपूर्ण प्रदर्शन समस्या है।


1

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

unordered_map<string,[yada]>

यहां तक ​​कि छोटे स्ट्रिंग ऑप्टिमाइज़ेशन के साथ, आपके पास एक चर-आकार का कंटेनर (स्ट्रिंग्स) एक और चर-आकार के कंटेनर (unordered_maps) के अंदर होता है। वास्तव में, छोटी स्ट्रिंग अनुकूलन वास्तव में इस मामले में सहायक के रूप में हानिकारक हो सकता है यदि आपकी तालिका बहुत विरल है, क्योंकि छोटे स्ट्रिंग अनुकूलन का अर्थ होगा कि हैश तालिका के प्रत्येक अप्रयुक्त सूचकांक अभी भी एसएस अनुकूलन (मेमोरी) के लिए अधिक मेमोरी का उपयोग sizeof(string)करेंगे। उस बिंदु पर अधिक बड़ा होना) जहां आपकी हैश टेबल की कुल मेमोरी ओवरहेड हो सकती है, जिसमें आप जो कुछ भी स्टोर कर रहे हैं, उससे अधिक खर्च हो सकता है, खासकर अगर यह एक स्थिति घटक की तरह एक सरल घटक है, तो इसके अलावा अधिक स्टड के साथ अधिक कैशे मिस हो जाती है हैश तालिका में एक प्रविष्टि से अगले करने के लिए प्राप्त करने के लिए।

मैं मान रहा हूं कि स्ट्रिंग किसी प्रकार की कुंजी है, जैसे घटक आईडी। यदि हां, तो यह पहले से ही चीजों को नाटकीय रूप से सस्ता बनाता है:

unordered_map<int,[yada]>

... यदि आप चाहते हैं कि उपयोगकर्ता के अनुकूल नाम होने के लाभ जो स्क्रिप्टर्स उपयोग कर सकते हैं, जैसे, तो नजरबंद तार आपको यहां दोनों दुनिया का सर्वश्रेष्ठ दे सकते हैं।

उन्होंने कहा, यदि आप स्ट्रिंग को घनीभूत रूप से उपयोग किए जाने वाले सूचकांकों की काफी कम रेंज में मैप कर सकते हैं, तो आप ऐसा करने में सक्षम हो सकते हैं:

vector<[yada]> // the index and key become one and the same

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

एक भोले उदाहरण के रूप में, एक वीडियो प्रोसेसिंग सॉफ्टवेयर जो इस के खिलाफ अपने कोड के सभी जोड़े:

// Abstract pixel that could be concretely represented by
// RGB, BGR, RGBA, BGRA, 1-bit channels, 8-bit channels, 
// 16-bit channels, 32-bit channels, grayscale, monochrome, 
// etc. pixels.
class IPixel
{
public:
    virtual ~IPixel() {}
    ...
};

छवि के स्तर पर अमूर्त की तुलना में एकल पिक्सेल स्तर पर अमूर्त करने के बिना दूर नहीं होने जा रहा है, क्योंकि एकल पिक्सेल स्तर पर अमूर्त करने का विचार पहले से ही बेहद अक्षम है ( vptrखुद को अक्सर पूरे पिक्सेल की तुलना में अधिक स्मृति खर्च होगी)। अक्सर लाखों पिक्सल का प्रतिनिधित्व करते हैं)। इसलिए अपने डेटा अभ्यावेदन में अग्रिम रूप से पर्याप्त विचार रखें ताकि आपको इस तरह के बुरे परिदृश्य का सामना न करना पड़े, और आदर्श रूप से और नहीं, लेकिन यहाँ मुझे लगता है कि यह इस सामान के बारे में सोचने लायक है क्योंकि आप इसे नहीं बनाना चाहते हैं अपने ECS के चारों ओर जटिल इंजन और पाते हैं कि ECS स्वयं उन तरीकों में अड़चन है, जिनके लिए आपको डिज़ाइन स्तर पर चीजों को बदलने की आवश्यकता होती है।

जैसा कि ईसीएस कैश की याद आती है, मेरी राय में डेवलपर्स अक्सर अपने ईसीएस को कैश-फ्रेंडली बनाने के लिए बहुत कोशिश करते हैं। यह हिरन के लिए बहुत कम धमाके का उत्पादन करना शुरू कर देता है ताकि आपके सभी घटकों को पूरी तरह से सन्निहित फैशन तक पहुंचने की कोशिश की जा सके, और अक्सर सभी जगह डेटा की नकल और फेरबदल किया जाएगा। यह आमतौर पर काफी अच्छा है, कहते हैं, सिर्फ रेडिक्स सॉर्ट घटक सूचकांकों को एक्सेस करने से पहले ताकि आप उन्हें इस तरह से एक्सेस कर रहे हैं जहां आप कम से कम एक मेमोरी क्षेत्र को कैश लाइन में लोड नहीं कर रहे हैं, केवल इसे निकालने के लिए, और फिर लोड करें यह सब एक ही लूप में फिर से एक ही कैश लाइन के एक अलग हिस्से तक पहुंचने के लिए है। और एक ECS को बोर्ड भर में अद्भुत दक्षता प्रदान करने की आवश्यकता नहीं है। यह एक इनपुट सिस्टम से उतना लाभ नहीं है, जितना कि भौतिकी या प्रतिपादन प्रणाली से है, इसलिए मैं "अच्छा" के लिए लक्ष्य बनाने की सलाह देता हूं। बोर्ड भर में दक्षता और "उत्कृष्ट" सिर्फ उन जगहों पर जहां आपको वास्तव में इसकी आवश्यकता है। उस ने कहा, का उपयोग करेंunordered_mapऔर stringयहाँ से बचने के लिए काफी आसान हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.