सी में कुछ बयानों का अनुकूलन करने वाले जीसीसी को कैसे रोका जाए?


107

पृष्ठ को गंदा करने के लिए (पृष्ठ तालिका प्रविष्टि में गंदे बिट पर स्विच करना), मैं पृष्ठ के पहले बाइट्स को स्पर्श करता हूं जैसे:

pageptr[0] = pageptr[0];

लेकिन व्यवहार में gcc डेड स्टोर एलिमिनेशन के कथन को अनदेखा कर देगा। इसे अनुकूलित करने के लिए gcc को रोकने के लिए, मैं कथन को इस प्रकार फिर से लिखता हूं:

volatile int tmp;
tmp = pageptr[0];
pageptr[0] = tmp;

ऐसा लगता है कि चाल काम करती है, लेकिन कुछ बदसूरत है। मैं जानना चाहूंगा कि क्या कोई निर्देश या वाक्यविन्यास है जिसका प्रभाव समान है? और मैं एक -O0ध्वज का उपयोग नहीं करना चाहता , क्योंकि यह शानदार प्रदर्शन जुर्माना भी लाएगा।


8
@MO -O0 अनुकूलन बंद कर देगा, लेकिन कार्यक्रम के प्रदर्शन को धीमा कर देता है। मैं इस कोड स्निपेट के अनुकूलन को रोकना चाहता हूं: P
ZelluX

मैं यह जोड़ना चाहता हूं कि अतीत में, यहां तक ​​कि -O0मृत कोड "अनुकूलन" को रोकने का उपयोग नहीं किया था, उदाहरण के लिए, जब जीसीसी का पता चलता है कि कुछ कोड का कोई प्रभाव नहीं है, तो यह बस इसे हटा देता है। AFAIK यह एक चरण पहले भी है -O0... लेकिन यह सिर्फ मेरा अनुभव है
चिकनी

जवाबों:


91

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

// Assuming pageptr is unsigned char * already...
unsigned char *pageptr = ...;
((unsigned char volatile *)pageptr)[0] = pageptr[0];

volatileसंकलक का निर्देश प्रकार क्वालीफायर स्मृति भंडार और भार के बारे में सख्त किया जाना है। इसका एक उद्देश्य volatileसंकलक को यह बताना है कि मेमोरी एक्सेस के साइड इफेक्ट्स हैं, और इसलिए इसे संरक्षित किया जाना चाहिए। इस स्थिति में, पृष्ठ दोष होने के कारण स्टोर का साइड इफेक्ट होता है, और आप चाहते हैं कि कंपाइलर पेज फॉल्ट को संरक्षित करे।

इस तरह, आसपास के कोड को अभी भी अनुकूलित किया जा सकता है, और आपका कोड अन्य कंपाइलरों के लिए पोर्टेबल है जो जीसीसी #pragmaया __attribute__सिंटैक्स को नहीं समझते हैं ।


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

3
Dietrich Epp का समाधान ARM4.1 कंपाइलर के तहत काम नहीं कर रहा है । यहां तक ​​कि ज़ेलुएक्स का समाधान भी काम नहीं कर रहा है। ARM4.1 के लिए यह काम करने के लिए वैकल्पिक विधि ZelluX के समाधान में है, ' अस्थायी ' को एक वैश्विक अस्थिर चर बनाते हैं ।
Oculus Dexter

1
कहा कि संकलक के लिए यह बहुत बुरा है।
एलेक्सी फ्रुंज़े

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

2
@jww: यह उपयोग उस ब्लॉग पोस्ट में वर्णित के साथ फिट बैठता है। volatileइसका मतलब है कि मेमोरी एक्सेस लिखित रूप में होनी चाहिए, जो कि वास्तव में हम चाहते हैं। दूसरे शब्दों में, हमने इसके बारे में ध्यान से सोचा है, और इसका मतलब है कि हम जो सोचते हैं उसका मतलब है।
डिट्रिच एप्प

184

आप उपयोग कर सकते हैं

#pragma GCC push_options
#pragma GCC optimize ("O0")

your code

#pragma GCC pop_options

GCC 4.4 के बाद से अनुकूलन को निष्क्रिय करने के लिए।

यदि आपको अधिक विवरण की आवश्यकता है, तो जीसीसी प्रलेखन देखें।


3
हालांकि यह ध्यान देने योग्य है कि यह केवल संपूर्ण कार्यों पर काम करता है, विशिष्ट प्रतिमाओं पर नहीं: gcc.gnu.org/oniltocs/gcc-4.8.2/gcc/… "" प्रत्येक बिंदु जो इस बिंदु के बाद परिभाषित किया गया है जैसे कि विशेषता है ( उस फ़ंक्शन के लिए ऑप्टिमाइज़ेशन ("STRING")) निर्दिष्ट किया गया था। "
सिरो सेंटिल्ली 郝海东 冠状 iro 事件 法轮功 '26

134

नए प्रैग्मस का उपयोग करने के बजाय, आप __attribute__((optimize("O0")))अपनी आवश्यकताओं के लिए भी उपयोग कर सकते हैं। यह केवल एक ही फ़ंक्शन पर लागू होने का लाभ है और एक ही फ़ाइल में परिभाषित सभी फ़ंक्शन नहीं है।

उपयोग उदाहरण:

void __attribute__((optimize("O0"))) foo(unsigned char data) {
    // unmodifiable compiler code
}

3
क्या होगा यदि मैं एक -Olevelविकल्प का उपयोग नहीं कर रहा हूं, लेकिन मैंने उन व्यक्तियों के विकल्पों का उपयोग किया है जो इसे हमेशा चालू करते हैं? (मेरे मामले में, मैं यह निर्धारित नहीं कर सकता कि कौन सा व्यक्तिगत अनुकूलन विकल्प है जो कोड को तोड़ रहा है)
user2284570
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.