2012-04-18 23 views
8

ऐसा नहीं है कि देखने के लिए आसान है:कई मॉड्यूलस संचालन पर तार्किक संचालन अनुकूलित?

(i % 3 == 0) && (i % 5 == 0) 

को सरल किया जा सकता है:

(i % 15 == 0) 

फिर भी जीसीसी के उत्पादन में देख, यह इस यहां तक ​​कि उच्च अनुकूलन के स्तर पर नहीं किया जाता है लगता है।

क्या कोई भी कंपाइलर इस तरह के अनुकूलन करता है, या क्या कोई अच्छा कारण है कि ये दो परीक्षण अर्थात् समकक्ष नहीं हैं?

संपादित करें: जो लोग कहते हैं कि यह एक किनारा मामला है, निम्नलिखित एक समान मामला है के जवाब में:

(i < 3) && (i < 5) 

कोई भी संख्या कम से कम 3, हमेशा होना चाहिए कम से कम 5. दूसरे टेस्ट अनावश्यक है।

मैं भी जवाब के जवाब में निम्नलिखित जोड़ने के लिए है कि संकलक अगर वातावरण प्रभावित होता है पता नहीं कर सकते हैं ... इस कोड को देखो करना चाहते हैं:

करने के लिए "repz सेवानिवृत्त
void foo(void) 
{ 
    int i; 
    for (i = 0; i <= 10; i++) 
    { 
     if (i > 20) 
     { 
      puts("Hi"); 
     } 
    } 
} 

पूरे समारोह कम हो जाता है "जीसीसी द्वारा -O2 के साथ। मैं जो भी बात कर रहा हूं उससे कहीं अधिक जटिल है।

+1

मेरा अनुमान है कि शॉर्ट-सर्किट मूल्यांकन की गारंटी है ... – Anycorn

+0

अनुकूलन के लिए समान चर पर एकाधिक तुलनाओं के लिए सामान्य जांच में संकलक करें? यह एक फ्रिंज केस की तरह दिखता है ... – trutheality

+2

@ एनीकॉर्न, क्या आप कह रहे हैं कि 'i' का मूल्यांकन करने से दुष्प्रभाव हो सकते हैं, और संकलक यह नहीं करता है कि यह करता है या नहीं? – ikegami

उत्तर

5

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

+0

मुझे लगता है कि आप * पर्याप्त * में मतलब है। लेकिन हाँ, मैं आपसे सहमत हूं। – Matt

+1

मेरा व्याकरण सही था। विषय अभी भी "कोई नहीं" है, जो नकारात्मक अर्थशास्त्र प्रदान करता है। :-) –

3

आपका उदाहरण अपेक्षाकृत सरल है और वास्तव में एक ही ऑपरेशन में घुलना आसान है। हालांकि, इस तरह के एक बयान का सामान्य मामला उतना आसान नहीं है। उदाहरण के लिए, निम्नलिखित लें:

((++i) % 3 == 0) && ((++i) % 5 == 0) 

यह परिवर्तन के रूप में आसानी से एक सिंगल मापांक आपरेशन करने के लिए नीचे सरलीकृत नहीं किया जा सकता (मैं जानता हूँ कि इस बयान इसके साथ अन्य समस्याओं के सभी प्रकार है, लेकिन बात यह है कि समस्या 'isn जब आप एक साधारण चर संदर्भ के अलावा कुछ भी उपयोग कर रहे हैं तो सरल के रूप में टी)। आमतौर पर कंपाइलर्स यह देखने के लिए नहीं देख पाएंगे कि आपके मामले में केवल साधारण चर शामिल हैं और सामान्य मामले की तुलना में इसे अलग-अलग अनुकूलित करते हैं; वे जब भी संभव हो अनुकूलन अनुकूल और अनुमानित रखने की कोशिश करते हैं।

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

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

+0

मैं असहमत हूं। कॉम्पलर सामान्य उप-अभिव्यक्तियों को खोजने में अच्छे होते हैं (जिनमें से केवल 'i' एक मामूली मामला है) और उनके उपयोग के आसपास अनुकूलित करना। –

+1

@ आर ..- यह वास्तव में एक आम उप अभिव्यक्ति के रूप में वर्गीकृत नहीं है, हालांकि। सीएसई ऑप्टिमाइज़ेशन एक उप-घटक की तलाश करते हैं जिसमें कई कथन सामान्य होते हैं और फिर अभिव्यक्ति को कई बार फिर से गणना करने के बजाय प्री-कैश किए गए मान का उपयोग करते हैं। यहां, एकमात्र आम हिस्सा 'i%' है, जो पूर्ण विवरण नहीं है और गणना योग्य नहीं है। ओपी क्या मांग रहा है ऑप्टिमाइज़ेशन के "गणितीय ताकत में कमी" परिवार से अधिक निकटता से संबंधित है। – bta

+0

इन सबके अतिरिक्त, याद रखें कि '&&' ऑपरेटर अनुक्रम बिंदु ("शॉर्ट सर्किट" ऑपरेशन के लिए) प्रस्तुत करता है। यदि बाएं हाथ की ओर शून्य का मूल्यांकन होता है, तो दाईं ओर की तरफ निष्पादित नहीं किया जाता है। शामिल कई संभावित दुष्प्रभावों के कारण, संकलक एक अनुक्रम बिंदु को अनुकूलित करने में बहुत संकोचजनक होने की संभावना है। ऐसा आसान मामलों के लिए आसान लगता है लेकिन एक सामान्य समस्या के रूप में, यह करना बहुत कठिन है। – bta

1

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

सामान्य रूप से, परिशुद्धता सीमा और अतिप्रवाह की संभावना के कारण गणितीय रिफैक्टरिंग लागू नहीं की जा सकती है। हालांकि मुझे नहीं लगता कि यह एक मुद्दा है।

संबंधित मुद्दे